You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@inlong.apache.org by do...@apache.org on 2021/07/13 04:38:20 UTC

[incubator-inlong] branch new-web-client created (now a6d697d)

This is an automated email from the ASF dual-hosted git repository.

dockerzhang pushed a change to branch new-web-client
in repository https://gitbox.apache.org/repos/asf/incubator-inlong.git.


      at a6d697d  fix(request): request menu css issue

This branch includes the following new commits:

     new 95f9b51  feat(*): rebuild console
     new 8493119  feat(issue): issue completed
     new 47b69ec  feat(broker): broker complete
     new 0e0143a  feat(broker):broker detail page complete
     new 83d771e  feat(broker):topic page complete
     new 9cd056f  feat(broker):topic detail page complete
     new e54f143  feat(cluster): cluster manger done
     new a074953  fix(eslint): fix eslint error
     new 20ec601  fix(request): request data handle
     new a6d697d  fix(request): request menu css issue

The 10 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[incubator-inlong] 08/10: fix(eslint): fix eslint error

Posted by do...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dockerzhang pushed a commit to branch new-web-client
in repository https://gitbox.apache.org/repos/asf/incubator-inlong.git

commit a074953f50a6e872dcf2b3e8f8117f72b7000b91
Author: zakwu <12...@qq.com>
AuthorDate: Tue Jun 30 16:21:06 2020 +0800

    fix(eslint): fix eslint error
---
 web/.eslintrc                          |   4 +-
 web/package.json                       |   2 +-
 web/src/components/Tablex/index.tsx    |   4 +-
 web/src/components/TitleWrap/index.tsx |   2 +-
 web/src/constants/broker.ts            |   6 +-
 web/src/constants/person.ts            |   2 +-
 web/src/constants/topic.ts             |   6 +-
 web/src/defaultSettings.js             |  10 +-
 web/src/hooks/index.ts                 |   6 +-
 web/src/pages/Broker/commonModal.tsx   |  85 +++---
 web/src/pages/Broker/detail.tsx        | 419 ++++++++++++++++-----------
 web/src/pages/Broker/index.tsx         |  79 ++---
 web/src/pages/Broker/query.tsx         |  70 ++---
 web/src/pages/Cluster/index.tsx        |  99 ++++---
 web/src/pages/Topic/commonModal.tsx    | 126 ++++----
 web/src/pages/Topic/detail.tsx         | 512 ++++++++++++++++++++-------------
 web/src/pages/Topic/index.tsx          | 180 +++++++-----
 web/src/pages/Topic/query.tsx          |  99 ++++---
 web/src/router.tsx                     |   1 +
 web/src/utils/index.ts                 |   9 +-
 20 files changed, 988 insertions(+), 733 deletions(-)

diff --git a/web/.eslintrc b/web/.eslintrc
index 7abddfd..472dd8d 100644
--- a/web/.eslintrc
+++ b/web/.eslintrc
@@ -21,6 +21,8 @@
   },
   "rules": {
     "@typescript-eslint/no-explicit-any": 0,
-    "@typescript-eslint/explicit-function-return-type": 0
+    "@typescript-eslint/explicit-function-return-type": 0,
+    "jsx-a11y/anchor-is-valid": 0,
+    "react-hooks/exhaustive-deps": 0
   }
 }
diff --git a/web/package.json b/web/package.json
index 5b8fefc..19ecc93 100644
--- a/web/package.json
+++ b/web/package.json
@@ -20,7 +20,7 @@
   },
   "scripts": {
     "analyze": "source-map-explorer 'build/static/js/*.js'",
-    "start": "react-app-rewired start",
+    "start": "EXTEND_ESLINT=true react-app-rewired start",
     "build": "react-app-rewired build",
     "test": "react-app-rewired test",
     "commit": "git cz",
diff --git a/web/src/components/Tablex/index.tsx b/web/src/components/Tablex/index.tsx
index 20d0cea..ec41277 100644
--- a/web/src/components/Tablex/index.tsx
+++ b/web/src/components/Tablex/index.tsx
@@ -35,7 +35,7 @@ const Comp = (props: ComProps) => {
     isTruePagination,
     showSearch = true,
     searchWidth = 8,
-    searchStyle = {}
+    searchStyle = {},
   } = props;
   const [filterKey, setFilterKey] = useState(defaultSearchKey);
   // 自动增加排序
@@ -86,7 +86,7 @@ const Comp = (props: ComProps) => {
   return (
     <>
       {showSearch && filterFnX && (
-        <Row gutter={20} className="mb10" style={{position: 'relative'}}>
+        <Row gutter={20} className="mb10" style={{ position: 'relative' }}>
           <Col span={searchWidth} style={{ padding: 0, ...searchStyle }}>
             <Tooltip title={filterKey}>
               <Search
diff --git a/web/src/components/TitleWrap/index.tsx b/web/src/components/TitleWrap/index.tsx
index cf2c3f3..47624f4 100644
--- a/web/src/components/TitleWrap/index.tsx
+++ b/web/src/components/TitleWrap/index.tsx
@@ -9,7 +9,7 @@ interface ComProps {
 }
 
 const Comp = (props: ComProps) => {
-  const {hasSplit = true} = props;
+  const { hasSplit = true } = props;
 
   return (
     <div style={props.wrapperStyle} className={hasSplit ? 'split-border' : ''}>
diff --git a/web/src/constants/broker.ts b/web/src/constants/broker.ts
index 7270aae..bc6ac45 100644
--- a/web/src/constants/broker.ts
+++ b/web/src/constants/broker.ts
@@ -5,7 +5,7 @@ export const BROKER_INFO_ZH_MAP = {
   brokerIp: 'BrokerIP',
   brokerPort: 'BrokerPort',
   brokerTLSPort: 'TLS端口',
-  brokerVersion: "版本",
+  brokerVersion: '版本',
   enableTLS: '启用TLS',
   isAutoForbidden: '自动屏蔽',
   isBrokerOnline: 'broker注册',
@@ -18,5 +18,5 @@ export const BROKER_INFO_ZH_MAP = {
   'runInfo.acceptPublish': 'broker可发布状态',
   'runInfo.acceptSubscribe': 'broker可订阅状态',
   'runInfo.numPartitions': 'broker分区数',
-  'runInfo.brokerManageStatus': 'broker运行状态'
-};
\ No newline at end of file
+  'runInfo.brokerManageStatus': 'broker运行状态',
+};
diff --git a/web/src/constants/person.ts b/web/src/constants/person.ts
index 1bd1b98..eadf34f 100644
--- a/web/src/constants/person.ts
+++ b/web/src/constants/person.ts
@@ -1,4 +1,4 @@
 export const PERSON_INFO_ZH_MAP = {
   createDate: '创建时间',
   createUser: '创建人',
-};
\ No newline at end of file
+};
diff --git a/web/src/constants/topic.ts b/web/src/constants/topic.ts
index 1f1cf9c..d4c8abf 100644
--- a/web/src/constants/topic.ts
+++ b/web/src/constants/topic.ts
@@ -5,6 +5,6 @@ export const TOPIC_INFO_ZH_MAP = {
   totalRunNumPartCount: '运行分区数',
   isSrvAcceptPublish: '可发布',
   isSrvAcceptSubscribe: '可订阅',
-  enableAuthControl: "权限受控",
-  groupCount: '授权消费组'
-};
\ No newline at end of file
+  enableAuthControl: '权限受控',
+  groupCount: '授权消费组',
+};
diff --git a/web/src/defaultSettings.js b/web/src/defaultSettings.js
index beebbb5..684a9a3 100644
--- a/web/src/defaultSettings.js
+++ b/web/src/defaultSettings.js
@@ -1,6 +1,6 @@
 export default {
-    "layout": "sidemenu",
-    "contentWidth": "Fluid",
-    "navTheme": "dark",
-    "primaryColor": "#1890ff"
-}
\ No newline at end of file
+  layout: 'sidemenu',
+  contentWidth: 'Fluid',
+  navTheme: 'dark',
+  primaryColor: '#1890ff',
+};
diff --git a/web/src/hooks/index.ts b/web/src/hooks/index.ts
index ae1eecf..488569c 100644
--- a/web/src/hooks/index.ts
+++ b/web/src/hooks/index.ts
@@ -33,12 +33,12 @@ axios.interceptors.response.use(
     }
 
     // set object outside data into it
-    const res = Object.assign({}, data)
+    const res = Object.assign({}, data);
     delete res.errCode;
     delete res.errMsg;
     res.data = Object.assign(res.data, {
-      ...res
-    })
+      ...res,
+    });
     return res || [];
   },
   function(error) {
diff --git a/web/src/pages/Broker/commonModal.tsx b/web/src/pages/Broker/commonModal.tsx
index 26480c4..8dc8654 100644
--- a/web/src/pages/Broker/commonModal.tsx
+++ b/web/src/pages/Broker/commonModal.tsx
@@ -1,10 +1,10 @@
-import {boolean2Chinese} from "@/utils";
-import Table from "@/components/Tablex";
-import {Col, Form, Input, Row} from "antd";
-import Modal, {OKProps} from "@/components/Modalx";
-import React from "react";
-import Query from "@/pages/Broker/query";
-import {FormProps} from "antd/lib/form";
+import { boolean2Chinese } from '@/utils';
+import Table from '@/components/Tablex';
+import { Col, Form, Input, Row } from 'antd';
+import Modal, { OKProps } from '@/components/Modalx';
+import React from 'react';
+import Query from '@/pages/Broker/query';
+import { FormProps } from 'antd/lib/form';
 
 export const OPTIONS = [
   {
@@ -26,7 +26,6 @@ export const OPTIONS = [
 ];
 export const OPTIONS_VALUES = OPTIONS.map(t => t.value);
 
-
 // interface
 export declare type BrokerData = any[];
 export interface BrokerResultData {
@@ -89,13 +88,7 @@ const renderBrokerOptions = (modalParams: any, dataSource: any[]) => {
       render: (t: string) => boolean2Chinese(t),
     },
   ];
-  return (
-    <Table
-      columns={columns}
-      dataSource={dataSource}
-      rowKey="brokerId"
-    />
-  );
+  return <Table columns={columns} dataSource={dataSource} rowKey="brokerId" />;
 };
 const renderNewBroker = (form: any) => {
   const brokerFormArr = [
@@ -161,18 +154,26 @@ const renderNewBroker = (form: any) => {
   );
 };
 const renderEditBroker = (modalParams: any, form: FormProps['form']) => {
-  const {params: p} = modalParams;
-  const pickArr = ['numPartitions', 'unflushThreshold', 'unflushInterval', 'deleteWhen', 'deletePolicy', 'acceptPublish', 'acceptSubscribe'];
-  let brokerFormArr : Array<{
+  const { params: p } = modalParams;
+  const pickArr = [
+    'numPartitions',
+    'unflushThreshold',
+    'unflushInterval',
+    'deleteWhen',
+    'deletePolicy',
+    'acceptPublish',
+    'acceptSubscribe',
+  ];
+  const brokerFormArr: Array<{
     name: string;
     defaultValue: string;
   }> = [];
   pickArr.forEach(t => {
     brokerFormArr.push({
       name: t,
-      defaultValue: p[t]
-    })
-  })
+      defaultValue: p[t],
+    });
+  });
 
   return (
     <Form form={form}>
@@ -204,8 +205,8 @@ const renderBrokerStateChange = (modalParams: any) => {
   );
 };
 export const onOpenModal = (p: BrokerModalProps) => {
-  const {type, title, updateFunction, params} = p;
-  if(typeof params === 'function') {
+  const { type, title, updateFunction, params } = p;
+  if (typeof params === 'function') {
     p.params = params();
   }
   updateFunction((m: any) => {
@@ -217,19 +218,19 @@ export const onOpenModal = (p: BrokerModalProps) => {
       title,
       onOk: (p: OKProps) => {
         updateFunction((m: any) => {
-          if(type === 'newBroker' || type === 'editBroker') {
-            p.params = f && f.getFieldsValue()
+          if (type === 'newBroker' || type === 'editBroker') {
+            p.params = f && f.getFieldsValue();
           }
           m.okParams = p;
           m.isOk = Date.now();
-        })
+        });
       },
       onCancel: () => {
         updateFunction((m: any) => {
           m.visible = false;
           m.isOk = null;
-        })
-      }
+        });
+      },
     });
   });
 };
@@ -240,7 +241,7 @@ interface ComProps {
 }
 let f: FormProps['form'];
 const Comp = (props: ComProps) => {
-  const {modalParams, data} = props;
+  const { modalParams, data } = props;
   const [form] = Form.useForm();
   f = form;
 
@@ -248,16 +249,26 @@ const Comp = (props: ComProps) => {
     <Modal {...modalParams}>
       <div>
         {modalParams.type &&
-        OPTIONS_VALUES.includes(modalParams.type) && renderBrokerOptions(modalParams, data.filter((t: BrokerResultData) =>
-          modalParams.params.includes(t.brokerId)
-        ))}
+          OPTIONS_VALUES.includes(modalParams.type) &&
+          renderBrokerOptions(
+            modalParams,
+            data.filter((t: BrokerResultData) =>
+              modalParams.params.includes(t.brokerId)
+            )
+          )}
         {modalParams.type === 'newBroker' && renderNewBroker(form)}
-        {modalParams.type === 'editBroker' && renderEditBroker(modalParams, form)}
-        {modalParams.type === 'brokerStateChange' && renderBrokerStateChange(modalParams)}
+        {modalParams.type === 'editBroker' &&
+          renderEditBroker(modalParams, form)}
+        {modalParams.type === 'brokerStateChange' &&
+          renderBrokerStateChange(modalParams)}
       </div>
-      <Query fire={modalParams.isOk} params={modalParams.okParams} type={modalParams.query || modalParams.type} />
+      <Query
+        fire={modalParams.isOk}
+        params={modalParams.okParams}
+        type={modalParams.query || modalParams.type}
+      />
     </Modal>
-  )
+  );
 };
 
-export default Comp;
\ No newline at end of file
+export default Comp;
diff --git a/web/src/pages/Broker/detail.tsx b/web/src/pages/Broker/detail.tsx
index b622dc7..28a7d06 100644
--- a/web/src/pages/Broker/detail.tsx
+++ b/web/src/pages/Broker/detail.tsx
@@ -1,17 +1,17 @@
-import React, {ReactNode, useContext, useState} from 'react';
+import React, { ReactNode, useContext, useState } from 'react';
 import GlobalContext from '@/context/globalContext';
 import Breadcrumb from '@/components/Breadcrumb';
 import Table from '@/components/Tablex';
 import TitleWrap from '@/components/TitleWrap';
-import {Form, Button, Spin, Col, Row, Switch, Tabs} from 'antd';
+import { Form, Button, Spin, Col, Row, Switch, Tabs } from 'antd';
 import { useImmer } from 'use-immer';
 import './index.less';
 import { useRequest } from '@/hooks';
-import {useParams} from 'react-router-dom';
-import {boolean2Chinese, transParamsWithConstantsMap} from "@/utils";
-import {BROKER_INFO_ZH_MAP} from "@/constants/broker";
-import tableFilterHelper from "@/components/Tablex/tableFilterHelper";
-import CommonModal, {OPTIONS, onOpenModal, BrokerData} from './commonModal'
+import { useParams } from 'react-router-dom';
+import { boolean2Chinese, transParamsWithConstantsMap } from '@/utils';
+import { BROKER_INFO_ZH_MAP } from '@/constants/broker';
+import tableFilterHelper from '@/components/Tablex/tableFilterHelper';
+import CommonModal, { OPTIONS, onOpenModal, BrokerData } from './commonModal';
 
 declare type BrokerQueryData = {
   withDetail: boolean;
@@ -23,7 +23,7 @@ declare type TopicQueryData = {
   brokerId: string;
 };
 
-const {TabPane} = Tabs;
+const { TabPane } = Tabs;
 
 const Detail: React.FC = () => {
   const { id } = useParams();
@@ -33,165 +33,197 @@ const Detail: React.FC = () => {
   const [acceptPublish, setAcceptPublish] = useState<any>(false);
   const [acceptSubscribe, setAcceptSubscribe] = useState<any>(false);
   const [filterData, updateFilterData] = useImmer<any>({});
-  const queryBrokerConf = useRequest<any>((data: BrokerQueryData = {
-    withDetail: true,
-    brokerId: id,
-  }) => ({
-    url: '/api/op_query/admin_query_broker_run_status',
-    data: {
-      ...data
-    }
-  }), {
-    onSuccess: data => {
-      setAcceptPublish(data[0]['acceptPublish'] === 'true');
-      setAcceptSubscribe(data[0]['acceptSubscribe'] === 'true');
-    }
-  });
-  const queryTopicInfo = useRequest<any>((data: TopicQueryData = {
-    withTopic: true,
-    brokerId: id,
-  }) => ({
-    url: '/api/op_query/admin_query_broker_configure',
-    data: {
-      ...data
+  const queryBrokerConf = useRequest<any>(
+    (
+      data: BrokerQueryData = {
+        withDetail: true,
+        brokerId: id,
+      }
+    ) => ({
+      url: '/api/op_query/admin_query_broker_run_status',
+      data: {
+        ...data,
+      },
+    }),
+    {
+      onSuccess: data => {
+        setAcceptPublish(data[0]['acceptPublish'] === 'true');
+        setAcceptSubscribe(data[0]['acceptSubscribe'] === 'true');
+      },
     }
-  }));
+  );
+  const queryTopicInfo = useRequest<any>(
+    (
+      data: TopicQueryData = {
+        withTopic: true,
+        brokerId: id,
+      }
+    ) => ({
+      url: '/api/op_query/admin_query_broker_configure',
+      data: {
+        ...data,
+      },
+    })
+  );
 
   // render
   const renderConf = () => {
-    const columns = [{
-      title: '类别',
-      dataIndex: `type`,
-    },
-    {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'acceptPublish'),
-      dataIndex: 'acceptPublish',
-      render: (t: string) => boolean2Chinese(t),
-    },
-    {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'acceptSubscribe'),
-      dataIndex: 'acceptSubscribe',
-      render: (t: string) => boolean2Chinese(t),
-    },
-    {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'unflushThreshold'),
-      dataIndex: 'unflushThreshold',
-    },
-    {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'unflushInterval'),
-      dataIndex: 'unflushInterval',
-    },
-    {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'deleteWhen'),
-      dataIndex: 'deleteWhen',
-    },
-    {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'deletePolicy'),
-      dataIndex: 'deletePolicy',
-    },
-    {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'numPartitions'),
-      dataIndex: 'numPartitions',
-    },
-    {
-      title: '操作',
-      render: (t:string, r: BrokerData) => {
-        return (<a onClick={() => onEditConf(r)}>编辑</a>)
-      }
-    }];
-    const {data} = queryBrokerConf;
-    if(!data || !data[0]) return null;
-    const {BrokerSyncStatusInfo} = data[0];
+    const columns = [
+      {
+        title: '类别',
+        dataIndex: `type`,
+      },
+      {
+        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'acceptPublish'),
+        dataIndex: 'acceptPublish',
+        render: (t: string) => boolean2Chinese(t),
+      },
+      {
+        title: transParamsWithConstantsMap(
+          BROKER_INFO_ZH_MAP,
+          'acceptSubscribe'
+        ),
+        dataIndex: 'acceptSubscribe',
+        render: (t: string) => boolean2Chinese(t),
+      },
+      {
+        title: transParamsWithConstantsMap(
+          BROKER_INFO_ZH_MAP,
+          'unflushThreshold'
+        ),
+        dataIndex: 'unflushThreshold',
+      },
+      {
+        title: transParamsWithConstantsMap(
+          BROKER_INFO_ZH_MAP,
+          'unflushInterval'
+        ),
+        dataIndex: 'unflushInterval',
+      },
+      {
+        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'deleteWhen'),
+        dataIndex: 'deleteWhen',
+      },
+      {
+        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'deletePolicy'),
+        dataIndex: 'deletePolicy',
+      },
+      {
+        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'numPartitions'),
+        dataIndex: 'numPartitions',
+      },
+      {
+        title: '操作',
+        render: (t: string, r: BrokerData) => {
+          return <a onClick={() => onEditConf(r)}>编辑</a>;
+        },
+      },
+    ];
+    const { data } = queryBrokerConf;
+    if (!data || !data[0]) return null;
+    const { BrokerSyncStatusInfo } = data[0];
     const dataSource = [];
     dataSource.push({
       type: '缺省配置',
-      ...BrokerSyncStatusInfo.curBrokerDefaultConfInfo
+      ...BrokerSyncStatusInfo.curBrokerDefaultConfInfo,
     });
     dataSource.push({
       type: '最近上报',
-      ...BrokerSyncStatusInfo.reportedBrokerDefaultConfInfo
+      ...BrokerSyncStatusInfo.reportedBrokerDefaultConfInfo,
     });
     dataSource.push({
       type: '最近下发',
-      ...BrokerSyncStatusInfo.lastPushBrokerDefaultConfInfo
+      ...BrokerSyncStatusInfo.lastPushBrokerDefaultConfInfo,
     });
 
     return <Table columns={columns} dataSource={dataSource} rowKey="type" />;
-  }
+  };
   const renderTopics = (type: string): ReactNode => {
-    const columns = [{
-      title: 'topicName',
-      dataIndex: `topicName`,
-    },
-    {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'numPartitions'),
-      dataIndex: 'numPartitions',
-    },
-    {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'acceptPublish'),
-      dataIndex: 'acceptPublish',
-      render: (t: string) => boolean2Chinese(t),
-    },
-    {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'acceptSubscribe'),
-      dataIndex: 'acceptSubscribe',
-      render: (t: string) => boolean2Chinese(t),
-    },
-    {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'unflushThreshold'),
-      dataIndex: 'unflushThreshold',
-    },
-    {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'unflushInterval'),
-      dataIndex: 'unflushInterval',
-    },
-    {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'deleteWhen'),
-      dataIndex: 'deleteWhen',
-    },
-    {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'deletePolicy'),
-      dataIndex: 'deletePolicy',
-    }];
-    const {data} = queryBrokerConf;
-    if(!data || !data[0]) return null;
-    const {BrokerSyncStatusInfo} = data[0];
+    const columns = [
+      {
+        title: 'topicName',
+        dataIndex: `topicName`,
+      },
+      {
+        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'numPartitions'),
+        dataIndex: 'numPartitions',
+      },
+      {
+        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'acceptPublish'),
+        dataIndex: 'acceptPublish',
+        render: (t: string) => boolean2Chinese(t),
+      },
+      {
+        title: transParamsWithConstantsMap(
+          BROKER_INFO_ZH_MAP,
+          'acceptSubscribe'
+        ),
+        dataIndex: 'acceptSubscribe',
+        render: (t: string) => boolean2Chinese(t),
+      },
+      {
+        title: transParamsWithConstantsMap(
+          BROKER_INFO_ZH_MAP,
+          'unflushThreshold'
+        ),
+        dataIndex: 'unflushThreshold',
+      },
+      {
+        title: transParamsWithConstantsMap(
+          BROKER_INFO_ZH_MAP,
+          'unflushInterval'
+        ),
+        dataIndex: 'unflushInterval',
+      },
+      {
+        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'deleteWhen'),
+        dataIndex: 'deleteWhen',
+      },
+      {
+        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'deletePolicy'),
+        dataIndex: 'deletePolicy',
+      },
+    ];
+    const { data } = queryBrokerConf;
+    if (!data || !data[0]) return null;
+    const { BrokerSyncStatusInfo } = data[0];
     let dataSource: any[] = [];
-    if(type === 'cur') {
+    if (type === 'cur') {
       dataSource = BrokerSyncStatusInfo.curBrokerTopicSetConfInfo;
-    } else if(type === 'lastPush') {
+    } else if (type === 'lastPush') {
       dataSource = BrokerSyncStatusInfo.lastPushBrokerTopicSetConfInfo;
-    } else if(type === 'lastReported') {
+    } else if (type === 'lastReported') {
       dataSource = BrokerSyncStatusInfo.reportedBrokerTopicSetConfInfo;
     }
 
-    return <Table columns={columns}
-                  dataSource={dataSource}
-                  rowKey={r => type + r.topicName}
-                  dataSourceX={filterData.list}
-                  searchPlaceholder="请输入TopicName搜索"
-                  searchStyle={{
-                    position: 'absolute',
-                    top: '-55px',
-                    right: '10px',
-                    zIndex: 1
-                  }}
-                  filterFnX={value =>
-                    tableFilterHelper({
-                      key: value,
-                      srcArray: dataSource,
-                      targetArray: filterData.list,
-                      updateFunction: res =>
-                        updateFilterData(filterData => {
-                          filterData.list = res;
-                        }),
-                      filterList: [
-                        'topicName',
-                      ],
-                    })
-                  }
-    />;
-  }
+    return (
+      <Table
+        columns={columns}
+        dataSource={dataSource}
+        rowKey={r => type + r.topicName}
+        dataSourceX={filterData.list}
+        searchPlaceholder="请输入TopicName搜索"
+        searchStyle={{
+          position: 'absolute',
+          top: '-55px',
+          right: '10px',
+          zIndex: 1,
+        }}
+        filterFnX={value =>
+          tableFilterHelper({
+            key: value,
+            srcArray: dataSource,
+            targetArray: filterData.list,
+            updateFunction: res =>
+              updateFilterData(filterData => {
+                filterData.list = res;
+              }),
+            filterList: ['topicName'],
+          })
+        }
+      />
+    );
+  };
 
   // event
   // acceptPublish && acceptSubscribe event
@@ -207,15 +239,17 @@ const Detail: React.FC = () => {
       type: 'brokerStateChange',
       title: `请确认操作`,
       updateFunction: updateModelParams,
-      params: { option, id: queryBrokerConf.data[0].brokerId,
+      params: {
+        option,
+        id: queryBrokerConf.data[0].brokerId,
         callback: () => {
           if (type === 'acceptPublish') {
             setAcceptPublish(e);
           } else if (type === 'acceptSubscribe') {
             setAcceptSubscribe(e);
           }
-        }
-      }
+        },
+      },
     });
   };
 
@@ -226,12 +260,17 @@ const Detail: React.FC = () => {
       updateFunction: updateModelParams,
       params: [queryBrokerConf.data[0].brokerId],
     });
-  }
+  };
 
   // new broker
   const onEditConf = (r: BrokerData) => {
-    onOpenModal({type: 'editBroker', title: '编辑Broker', updateFunction: updateModelParams, params: r})
-  }
+    onOpenModal({
+      type: 'editBroker',
+      title: '编辑Broker',
+      updateFunction: updateModelParams,
+      params: r,
+    });
+  };
 
   return (
     <Spin spinning={queryBrokerConf.loading && queryTopicInfo.loading}>
@@ -240,49 +279,80 @@ const Detail: React.FC = () => {
         appendParams={`Broker(${id})详情`}
       />
       <div className="main-container">
-        <TitleWrap title="运行状态" wrapperStyle={{position: 'relative'}}>
+        <TitleWrap title="运行状态" wrapperStyle={{ position: 'relative' }}>
           <div className="broker-detail-options-wrapper">
             <Switch
               className="mr10"
-              checked={acceptPublish} checkedChildren="订阅" unCheckedChildren="订阅"
+              checked={acceptPublish}
+              checkedChildren="订阅"
+              unCheckedChildren="订阅"
               onChange={e => onSwitchChange(e, 'acceptPublish')}
             />
             <Switch
               className="mr10"
-              checked={acceptSubscribe} checkedChildren="发布" unCheckedChildren="发布"
+              checked={acceptSubscribe}
+              checkedChildren="发布"
+              unCheckedChildren="发布"
               onChange={e => onSwitchChange(e, 'acceptSubscribe')}
             />
-            <Button className="mr10" type="primary" size="small" onClick={() => onOptions('online')}>
+            <Button
+              className="mr10"
+              type="primary"
+              size="small"
+              onClick={() => onOptions('online')}
+            >
               上线
             </Button>
-            <Button className="mr10" type="primary" size="small" onClick={() => onOptions('offline')}>
+            <Button
+              className="mr10"
+              type="primary"
+              size="small"
+              onClick={() => onOptions('offline')}
+            >
               下线
             </Button>
-            <Button className="mr10" type="primary" size="small"  onClick={() => onOptions('reload')}>
+            <Button
+              className="mr10"
+              type="primary"
+              size="small"
+              onClick={() => onOptions('reload')}
+            >
               重载
             </Button>
           </div>
           <Form form={form}>
             <Row gutter={24}>
-              {queryBrokerConf.data && Object.keys(queryBrokerConf.data[0]).map((t: string, index: number) => {
-                const label = transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, t);
-                const ignoreList = ['acceptPublish', 'brokerVersion', 'acceptSubscribe'];
-                if (queryBrokerConf.data[0][t] instanceof Object || !label || ignoreList.includes(t)) return null
-                return (<Col span={12} key={'queryBrokerConf' + index}>
-                  <Form.Item
-                    labelCol={{span: 12}}
-                    label={label}
-                  >
-                    {queryBrokerConf.data[0][t] + ''}
-                  </Form.Item>
-                </Col>)
-              })}
+              {queryBrokerConf.data &&
+                Object.keys(queryBrokerConf.data[0]).map(
+                  (t: string, index: number) => {
+                    const label = transParamsWithConstantsMap(
+                      BROKER_INFO_ZH_MAP,
+                      t
+                    );
+                    const ignoreList = [
+                      'acceptPublish',
+                      'brokerVersion',
+                      'acceptSubscribe',
+                    ];
+                    if (
+                      queryBrokerConf.data[0][t] instanceof Object ||
+                      !label ||
+                      ignoreList.includes(t)
+                    )
+                      return null;
+                    return (
+                      <Col span={12} key={'queryBrokerConf' + index}>
+                        <Form.Item labelCol={{ span: 12 }} label={label}>
+                          {queryBrokerConf.data[0][t] + ''}
+                        </Form.Item>
+                      </Col>
+                    );
+                  }
+                )}
             </Row>
           </Form>
         </TitleWrap>
-        <TitleWrap title="缺省配置">
-          {renderConf()}
-        </TitleWrap>
+        <TitleWrap title="缺省配置">{renderConf()}</TitleWrap>
         <TitleWrap title="Topic集合配置">
           <Tabs>
             <TabPane tab="当前配置" key="cur">
@@ -297,7 +367,10 @@ const Detail: React.FC = () => {
           </Tabs>
         </TitleWrap>
       </div>
-      <CommonModal modalParams={modalParams} data={[queryBrokerConf.data && queryBrokerConf.data[0]]} />
+      <CommonModal
+        modalParams={modalParams}
+        data={[queryBrokerConf.data && queryBrokerConf.data[0]]}
+      />
     </Spin>
   );
 };
diff --git a/web/src/pages/Broker/index.tsx b/web/src/pages/Broker/index.tsx
index bfd31d6..7cc91dc 100644
--- a/web/src/pages/Broker/index.tsx
+++ b/web/src/pages/Broker/index.tsx
@@ -2,48 +2,53 @@ import React, { useContext, useState } from 'react';
 import GlobalContext from '@/context/globalContext';
 import Breadcrumb from '@/components/Breadcrumb';
 import Table from '@/components/Tablex';
-import { Form, Select, Button, Spin, Switch, message} from 'antd';
+import { Form, Select, Button, Spin, Switch, message } from 'antd';
 import { useImmer } from 'use-immer';
 import { useRequest } from '@/hooks';
 import tableFilterHelper from '@/components/Tablex/tableFilterHelper';
 import { boolean2Chinese, transParamsWithConstantsMap } from '@/utils';
-import {BROKER_INFO_ZH_MAP} from '@/constants/broker';
+import { BROKER_INFO_ZH_MAP } from '@/constants/broker';
 import './index.less';
-import {Link} from "react-router-dom";
-import CommonModal, {OPTIONS, onOpenModal, BrokerResultData, BrokerData} from './commonModal'
+import { Link } from 'react-router-dom';
+import CommonModal, {
+  OPTIONS,
+  onOpenModal,
+  BrokerResultData,
+  BrokerData,
+} from './commonModal';
 
-const {Option} = Select;
+const { Option } = Select;
 const Broker: React.FC = () => {
   // column config
   const columns = [
     {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'brokerId'),
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'brokerId'),
       dataIndex: 'brokerId',
       fixed: 'left',
       render: (t: Array<any>) => <Link to={'/broker/' + t}>{t}</Link>,
     },
     {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'brokerIp'),
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'brokerIp'),
       dataIndex: 'brokerIp',
     },
     {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'brokerPort'),
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'brokerPort'),
       dataIndex: 'brokerPort',
     },
     {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'manageStatus'),
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'manageStatus'),
       dataIndex: 'manageStatus',
     },
     {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'runStatus'),
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'runStatus'),
       dataIndex: 'runStatus',
     },
     {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'subStatus'),
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'subStatus'),
       dataIndex: 'subStatus',
     },
     {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'acceptPublish'),
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'acceptPublish'),
       dataIndex: 'acceptPublish',
       render: (t: string, r: BrokerResultData) => {
         return (
@@ -55,7 +60,7 @@ const Broker: React.FC = () => {
       },
     },
     {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'acceptSubscribe'),
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'acceptSubscribe'),
       dataIndex: 'acceptSubscribe',
       render: (t: string, r: BrokerResultData) => {
         return (
@@ -67,42 +72,42 @@ const Broker: React.FC = () => {
       },
     },
     {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'isConfChanged'),
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'isConfChanged'),
       dataIndex: 'isConfChanged',
       render: (t: string) => boolean2Chinese(t),
     },
     {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'isConfLoaded'),
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'isConfLoaded'),
       dataIndex: 'isConfLoaded',
       render: (t: string) => boolean2Chinese(t),
     },
     {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'isBrokerOnline'),
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'isBrokerOnline'),
       dataIndex: 'isBrokerOnline',
       render: (t: string) => boolean2Chinese(t),
     },
     {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'acceptPublish'),
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'acceptPublish'),
       dataIndex: 'isBrokerOnline',
       render: (t: string) => boolean2Chinese(t),
     },
     {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'brokerTLSPort'),
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'brokerTLSPort'),
       dataIndex: 'brokerTLSPort',
       render: (t: string) => boolean2Chinese(t),
     },
     {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'enableTLS'),
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'enableTLS'),
       dataIndex: 'enableTLS',
       render: (t: boolean) => boolean2Chinese(t),
     },
     {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'isRepAbnormal'),
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'isRepAbnormal'),
       dataIndex: 'isRepAbnormal',
       render: (t: boolean) => boolean2Chinese(t),
     },
     {
-      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'isAutoForbidden'),
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'isAutoForbidden'),
       dataIndex: 'isAutoForbidden',
       render: (t: boolean) => boolean2Chinese(t),
     },
@@ -131,16 +136,19 @@ const Broker: React.FC = () => {
   const [brokerList, updateBrokerList] = useImmer<BrokerData>([]);
   const [form] = Form.useForm();
   // init query
-  const { data, loading, run } = useRequest<any, BrokerData>((data: BrokerResultData) => ({
-    url: '/api/op_query/admin_query_broker_run_status',
-    data: data,
-  }), {
-    onSuccess: data => {
-      updateBrokerList(d => {
-        Object.assign(d, data);
-      });
-    },
-  });
+  const { data, loading, run } = useRequest<any, BrokerData>(
+    (data: BrokerResultData) => ({
+      url: '/api/op_query/admin_query_broker_run_status',
+      data: data,
+    }),
+    {
+      onSuccess: data => {
+        updateBrokerList(d => {
+          Object.assign(d, data);
+        });
+      },
+    }
+  );
 
   // table event
   // acceptSubscribe && acceptPublish options
@@ -167,12 +175,17 @@ const Broker: React.FC = () => {
           updateBrokerList(d => {
             d[index][type] = e + '';
           });
-        }},
+        },
+      },
     });
   };
   // new broker
   const onNewBroker = () => {
-    onOpenModal({type: 'newBroker', title: '新建Broker', updateFunction: updateModelParams})
+    onOpenModal({
+      type: 'newBroker',
+      title: '新建Broker',
+      updateFunction: updateModelParams,
+    });
   };
   // online, offline, etc.
   const onOptionsChange = (type: string, r?: BrokerResultData) => {
diff --git a/web/src/pages/Broker/query.tsx b/web/src/pages/Broker/query.tsx
index 6f8b8e9..9e89789 100644
--- a/web/src/pages/Broker/query.tsx
+++ b/web/src/pages/Broker/query.tsx
@@ -1,9 +1,9 @@
 import * as React from 'react';
 import './index.less';
-import {OKProps} from "@/components/Modalx";
-import {useRequest} from "@/hooks";
-import {useContext, useEffect} from "react";
-import GlobalContext from "@/context/globalContext";
+import { OKProps } from '@/components/Modalx';
+import { useRequest } from '@/hooks';
+import { useContext, useEffect } from 'react';
+import GlobalContext from '@/context/globalContext';
 
 interface ComProps {
   fire: string;
@@ -12,15 +12,16 @@ interface ComProps {
 }
 
 const Comp = (props: ComProps) => {
-  const {fire} = props;
+  const { fire } = props;
   const { userInfo } = useContext(GlobalContext);
+  // eslint-disable-next-line
   useEffect(() => {
-    const {params, type} = props;
+    const { params, type } = props;
     dispatchAction(type, params);
   }, [fire, props]);
 
   const dispatchAction = (type: string, p: OKProps) => {
-    if(!fire) return null;
+    if (!fire) return null;
     let promise;
     switch (type) {
       case 'newBroker':
@@ -40,10 +41,11 @@ const Comp = (props: ComProps) => {
         break;
     }
 
-    promise && promise.then(t => {
-      const {callback} = p.params;
-      if(t.statusCode !== 0 && callback) callback(t);
-    })
+    promise &&
+      promise.then(t => {
+        const { callback } = p.params;
+        if (t.statusCode !== 0 && callback) callback(t);
+      });
   };
 
   const newBrokerQuery = useRequest<any, any>(
@@ -51,7 +53,7 @@ const Comp = (props: ComProps) => {
     { manual: true }
   );
   const newBroker = (p: OKProps) => {
-    const {params} = p;
+    const { params } = p;
     return newBrokerQuery.run({
       data: {
         ...params,
@@ -66,7 +68,7 @@ const Comp = (props: ComProps) => {
     { manual: true }
   );
   const editBroker = (p: OKProps) => {
-    const {params} = p;
+    const { params } = p;
     return updateBrokerQuery.run({
       data: {
         ...params,
@@ -82,13 +84,16 @@ const Comp = (props: ComProps) => {
   );
   const brokerOptions = (type: string, p: OKProps) => {
     const { params } = p;
-    return brokerOptionsQuery.run(`/api/op_modify/admin_${type}_broker_configure`, {
-      data: {
-        brokerId: params ? params?.join(',') : params?.selectBroker.join(','),
-        confModAuthToken: p.psw,
-        createUser: userInfo.userName,
-      },
-    });
+    return brokerOptionsQuery.run(
+      `/api/op_modify/admin_${type}_broker_configure`,
+      {
+        data: {
+          brokerId: params ? params?.join(',') : params?.selectBroker.join(','),
+          confModAuthToken: p.psw,
+          createUser: userInfo.userName,
+        },
+      }
+    );
   };
 
   const brokerAcceptPublishQuery = useRequest<any, any>(
@@ -97,30 +102,27 @@ const Comp = (props: ComProps) => {
   );
   const brokerAcceptPublish = (type: string, p: OKProps) => {
     const { params } = p;
-    let data: {
-      [key: string]: any;
-    };
-
-    data = {
+    const data: any = {
       brokerId: params.id,
       confModAuthToken: p.psw,
       createUser: userInfo.userName,
-    }
-    if(params.type === 'acceptPublish') {
+    };
+    if (params.type === 'acceptPublish') {
       data.isAcceptPublish = params.option;
     }
-    if(params.type === 'acceptSubscribe') {
+    if (params.type === 'acceptSubscribe') {
       data.isAcceptSubscribe = params.option;
     }
 
-    return brokerAcceptPublishQuery.run(`/api/op_modify/admin_set_broker_read_or_write`, {
-      data,
-    });
+    return brokerAcceptPublishQuery.run(
+      `/api/op_modify/admin_set_broker_read_or_write`,
+      {
+        data,
+      }
+    );
   };
 
-  return (
-    <></>
-  );
+  return <></>;
 };
 
 export default Comp;
diff --git a/web/src/pages/Cluster/index.tsx b/web/src/pages/Cluster/index.tsx
index 7164854..6b82403 100644
--- a/web/src/pages/Cluster/index.tsx
+++ b/web/src/pages/Cluster/index.tsx
@@ -2,11 +2,11 @@ import React, { useContext } from 'react';
 import GlobalContext from '@/context/globalContext';
 import Breadcrumb from '@/components/Breadcrumb';
 import Table from '@/components/Tablex';
-import { Form, Input, Button, Spin } from 'antd';
+import { Spin } from 'antd';
 import './index.less';
 import { useRequest } from '@/hooks';
-import Modal, {OKProps} from "@/components/Modalx";
-import {useImmer} from "use-immer";
+import Modal, { OKProps } from '@/components/Modalx';
+import { useImmer } from 'use-immer';
 
 interface ClusterResultData {
   groupName: string;
@@ -28,7 +28,7 @@ const Cluster: React.FC = () => {
   const [modalParams, updateModelParams] = useImmer<any>({
     title: '请确认操作',
   });
-  const { data, loading, run } = useRequest<any, any>(queryClusterList, {
+  const { data, loading } = useRequest<any, any>(queryClusterList, {
     formatResult: d => {
       return {
         list: d.data.map((t: any) => ({
@@ -38,10 +38,10 @@ const Cluster: React.FC = () => {
           index: t.index,
           port: t.port,
           nodeStatus: t.statusInfo.nodeStatus,
-          length: d.data.length
+          length: d.data.length,
         })),
       };
-    }
+    },
   });
   const columns = [
     {
@@ -51,10 +51,10 @@ const Cluster: React.FC = () => {
         return {
           children: t,
           props: {
-            rowSpan: index === 0 ? r.length : 0
-          }
-        }
-      }
+            rowSpan: index === 0 ? r.length : 0,
+          },
+        };
+      },
     },
     {
       title: '集群状态',
@@ -63,22 +63,22 @@ const Cluster: React.FC = () => {
         return {
           children: t,
           props: {
-            rowSpan: index === 0 ? r.length : 0
-          }
-        }
-      }
+            rowSpan: index === 0 ? r.length : 0,
+          },
+        };
+      },
     },
     {
       title: '节点名',
       render: (t: string, r: ClusterResultData) => {
         return `${r.groupName}-${r.hostName}`;
-      }
+      },
     },
     {
       title: 'IP地址',
       render: (t: string, r: ClusterResultData) => {
         return `${r.hostName}-${r.port}`;
-      }
+      },
     },
     {
       title: '节点名',
@@ -88,51 +88,50 @@ const Cluster: React.FC = () => {
       title: '操作',
       render: (t: string, r: ClusterResultData, index: number) => {
         return {
-          children: (<span className="options-wrapper">
-              <a onClick={() => onSwitchCluster(t, r)}>
-                切换
-              </a>
-          </span>),
+          children: (
+            <span className="options-wrapper">
+              <a onClick={() => onSwitchCluster(t, r)}>切换</a>
+            </span>
+          ),
           props: {
-            rowSpan: index === 0 ? r.length : 0
-          }
-        }
-      }
+            rowSpan: index === 0 ? r.length : 0,
+          },
+        };
+      },
     },
   ];
 
-  const switchClusterQuery = useRequest<any, any>((data?: ClusterResultData) => ({
-    url: '/api/op_modify/admin_transfer_current_master',
-    data,
-  }), { manual: true });
+  const switchClusterQuery = useRequest<any, any>(
+    (data?: ClusterResultData) => ({
+      url: '/api/op_modify/admin_transfer_current_master',
+      data,
+    }),
+    { manual: true }
+  );
   const onSwitchCluster = (t: string, r: ClusterResultData) => {
-      updateModelParams(d => {
-        d = Object.assign(d, {
-          visible: true,
-          onOk: (p: OKProps) => {
-            switchClusterQuery.run({
-              confModAuthToken: p.psw
-            })
-          },
-          onCancel: () => {
-            updateModelParams((m: any) => {
-              m.visible = false;
-            })
-          }
-        })
-      })
+    updateModelParams(d => {
+      d = Object.assign(d, {
+        visible: true,
+        onOk: (p: OKProps) => {
+          switchClusterQuery.run({
+            confModAuthToken: p.psw,
+          });
+        },
+        onCancel: () => {
+          updateModelParams((m: any) => {
+            m.visible = false;
+          });
+        },
+      });
+    });
   };
   return (
     <Spin spinning={loading}>
       <Breadcrumb breadcrumbMap={breadMap}></Breadcrumb>
       <div className="main-container">
-        <Table
-          columns={columns}
-          dataSource={data?.list}
-          rowKey="index"
-        ></Table>
+        <Table columns={columns} dataSource={data?.list} rowKey="index"></Table>
       </div>
-      <Modal {...modalParams} >
+      <Modal {...modalParams}>
         <div>
           确认<span className="enhance">切换</span>集群?
         </div>
diff --git a/web/src/pages/Topic/commonModal.tsx b/web/src/pages/Topic/commonModal.tsx
index 3200060..9d7783c 100644
--- a/web/src/pages/Topic/commonModal.tsx
+++ b/web/src/pages/Topic/commonModal.tsx
@@ -1,10 +1,10 @@
-import {boolean2Chinese} from "@/utils";
-import Table from "@/components/Tablex";
-import {Col, Form, Input, message, Row} from "antd";
-import Modal, {OKProps} from "@/components/Modalx";
-import React, {useState} from "react";
-import Query from "@/pages/Topic/query";
-import {FormProps} from "antd/lib/form";
+import { boolean2Chinese } from '@/utils';
+import Table from '@/components/Tablex';
+import { Col, Form, Input, message, Row } from 'antd';
+import Modal, { OKProps } from '@/components/Modalx';
+import React from 'react';
+import Query from '@/pages/Topic/query';
+import { FormProps } from 'antd/lib/form';
 
 export const OPTIONS = [
   {
@@ -17,13 +17,13 @@ export const OPTIONS_VALUES = OPTIONS.map(t => t.value);
 // interface
 export declare type TopicData = any[];
 export interface TopicResultData {
-  topicName: string,
-  infoCount: string,
-  totalCfgNumPart: string,
-  totalRunNumPartCount: string,
-  isSrvAcceptPublish: string|number,
-  isSrvAcceptSubscribe: string|number,
-  enableAuthControl: string|number,
+  topicName: string;
+  infoCount: string;
+  totalCfgNumPart: string;
+  totalRunNumPartCount: string;
+  isSrvAcceptPublish: string | number;
+  isSrvAcceptSubscribe: string | number;
+  enableAuthControl: string | number;
   [key: string]: any;
 }
 export interface TopicModalProps {
@@ -71,13 +71,7 @@ const renderTopicOptions = (modalParams: any, dataSource: any[]) => {
       render: (t: string) => boolean2Chinese(t),
     },
   ];
-  return (
-    <Table
-      columns={columns}
-      dataSource={dataSource}
-      rowKey="brokerId"
-    />
-  );
+  return <Table columns={columns} dataSource={dataSource} rowKey="brokerId" />;
 };
 const renderNewTopic = (form: any) => {
   const brokerFormArr = [
@@ -135,7 +129,7 @@ const renderNewTopic = (form: any) => {
   );
 };
 const renderChooseBroker = (modalParams: any) => {
-  let {params} = modalParams;
+  const { params } = modalParams;
   const columns = [
     {
       title: 'Broker',
@@ -175,18 +169,27 @@ const renderChooseBroker = (modalParams: any) => {
   );
 };
 const renderEditTopic = (modalParams: any, form: FormProps['form']) => {
-  const {params: p} = modalParams;
-  const pickArr = ['topicName', 'numPartitions', 'unflushThreshold', 'unflushInterval', 'deleteWhen', 'deletePolicy', 'acceptPublish', 'acceptSubscribe'];
-  let brokerFormArr : Array<{
+  const { params: p } = modalParams;
+  const pickArr = [
+    'topicName',
+    'numPartitions',
+    'unflushThreshold',
+    'unflushInterval',
+    'deleteWhen',
+    'deletePolicy',
+    'acceptPublish',
+    'acceptSubscribe',
+  ];
+  const brokerFormArr: Array<{
     name: string;
     defaultValue: string;
   }> = [];
   pickArr.forEach(t => {
     brokerFormArr.push({
       name: t,
-      defaultValue: p[t]
-    })
-  })
+      defaultValue: p[t],
+    });
+  });
 
   return (
     <Form form={form}>
@@ -212,8 +215,8 @@ const renderTopicStateChange = (modalParams: any) => {
 
   return (
     <div>
-      请确认<span className="enhance">{params.option}</span> 以下broker列表的 topic :
-      <span className="enhance">({params.topicName})</span> 的 Topic?
+      请确认<span className="enhance">{params.option}</span> 以下broker列表的
+      topic :<span className="enhance">({params.topicName})</span> 的 Topic?
       {renderChooseBroker(modalParams)}
     </div>
   );
@@ -244,12 +247,17 @@ const renderAuthorizeControlChange = (modalParams: any) => {
 
   return (
     <div>
-      请确认<span className="enhance">{params.value ? '启动' : '关闭'}topic<span className="enhance">({params.topicName})</span>的消费组授权控制</span>吗?
+      请确认
+      <span className="enhance">
+        {params.value ? '启动' : '关闭'}topic
+        <span className="enhance">({params.topicName})</span>的消费组授权控制
+      </span>
+      吗?
     </div>
   );
 };
 export const onOpenModal = (p: TopicModalProps) => {
-  const {type, title, updateFunction, params} = p;
+  const { type, title, updateFunction, params } = p;
   updateFunction((m: any) => {
     m.type = type;
     m.params = params;
@@ -259,30 +267,37 @@ export const onOpenModal = (p: TopicModalProps) => {
       title,
       onOk: (p: OKProps) => {
         updateFunction((m: any) => {
-          if(type === 'newTopic' || type === 'editTopic') {
+          if (type === 'newTopic' || type === 'editTopic') {
             p.params = Object.assign(f && f.getFieldsValue(), {
               callback: p.params.callback,
             });
           }
 
-          if(type === 'chooseBroker' || type === 'topicStateChange' || type === 'deleteTopic') {
-            if(!selectBroker.length) {
+          if (
+            type === 'chooseBroker' ||
+            type === 'topicStateChange' ||
+            type === 'deleteTopic'
+          ) {
+            if (!selectBroker.length) {
               message.error('至少选择一列!');
               return;
             }
 
             // end
-            if(type === 'chooseBroker') {
-              m.query = p.params.subType === 'edit' ? 'endEditChooseBroker' : 'endChooseBroker';
+            if (type === 'chooseBroker') {
+              m.query =
+                p.params.subType === 'edit'
+                  ? 'endEditChooseBroker'
+                  : 'endChooseBroker';
             }
             p.params = Object.assign({}, p.params, {
-              selectBroker
-            })
+              selectBroker,
+            });
           }
 
           m.okParams = p;
           m.isOk = Date.now();
-        })
+        });
       },
       onCancel: () =>
         updateFunction((m: any) => {
@@ -296,7 +311,7 @@ export const onOpenModal = (p: TopicModalProps) => {
 let selectBroker: any[] = [];
 let f: FormProps['form'];
 const Comp = (props: ComProps) => {
-  const {modalParams, data} = props;
+  const { modalParams, data } = props;
   const [form] = Form.useForm();
   f = form;
 
@@ -304,20 +319,31 @@ const Comp = (props: ComProps) => {
     <Modal {...modalParams}>
       <div>
         {modalParams.type &&
-        OPTIONS_VALUES.includes(modalParams.type) && renderTopicOptions(modalParams, data.filter((t: TopicResultData) =>
-          modalParams.params.includes(t.brokerId)
-        ))}
+          OPTIONS_VALUES.includes(modalParams.type) &&
+          renderTopicOptions(
+            modalParams,
+            data.filter((t: TopicResultData) =>
+              modalParams.params.includes(t.brokerId)
+            )
+          )}
         {modalParams.type === 'newTopic' && renderNewTopic(form)}
         {modalParams.type === 'chooseBroker' && renderChooseBroker(modalParams)}
         {modalParams.type === 'editTopic' && renderEditTopic(modalParams, form)}
-        {modalParams.type === 'topicStateChange' && renderTopicStateChange(modalParams)}
+        {modalParams.type === 'topicStateChange' &&
+          renderTopicStateChange(modalParams)}
         {modalParams.type === 'deleteTopic' && renderDeleteTopic(modalParams)}
-        {modalParams.type === 'deleteConsumeGroup' && renderDeleteConsumeGroup(modalParams)}
-        {modalParams.type === 'authorizeControl' && renderAuthorizeControlChange(modalParams)}
+        {modalParams.type === 'deleteConsumeGroup' &&
+          renderDeleteConsumeGroup(modalParams)}
+        {modalParams.type === 'authorizeControl' &&
+          renderAuthorizeControlChange(modalParams)}
       </div>
-     <Query fire={modalParams.isOk} params={modalParams.okParams} type={modalParams.visible && (modalParams.query || modalParams.type)} />
+      <Query
+        fire={modalParams.isOk}
+        params={modalParams.okParams}
+        type={modalParams.visible && (modalParams.query || modalParams.type)}
+      />
     </Modal>
-  )
+  );
 };
 
-export default Comp;
\ No newline at end of file
+export default Comp;
diff --git a/web/src/pages/Topic/detail.tsx b/web/src/pages/Topic/detail.tsx
index 37cb1e5..0c9965c 100644
--- a/web/src/pages/Topic/detail.tsx
+++ b/web/src/pages/Topic/detail.tsx
@@ -1,20 +1,22 @@
-import React, {ReactNode, useContext, useState} from 'react';
+import React, { ReactNode, useContext, useState } from 'react';
 import GlobalContext from '@/context/globalContext';
 import Breadcrumb from '@/components/Breadcrumb';
 import Table from '@/components/Tablex';
 import TitleWrap from '@/components/TitleWrap';
-import {Form, Button, Spin, Col, Row, Switch} from 'antd';
+import { Form, Button, Spin, Col, Row, Switch } from 'antd';
 import { useImmer } from 'use-immer';
 import './index.less';
 import { useRequest } from '@/hooks';
-import {useParams} from 'react-router-dom';
-import {boolean2Chinese, transParamsWithConstantsMap} from "@/utils";
-import tableFilterHelper from "@/components/Tablex/tableFilterHelper";
-import CommonModal, {onOpenModal, TopicResultData} from './commonModal';
-import BrokerModal, {BrokerData, BrokerModalProps, onOpenModal as onOpenBrokerModal} from '@/pages/Broker/commonModal';
-import {BROKER_INFO_ZH_MAP} from "@/constants/broker";
-import {PERSON_INFO_ZH_MAP} from "@/constants/person";
-import {TOPIC_INFO_ZH_MAP} from "@/constants/topic";
+import { useParams } from 'react-router-dom';
+import { boolean2Chinese, transParamsWithConstantsMap } from '@/utils';
+import tableFilterHelper from '@/components/Tablex/tableFilterHelper';
+import CommonModal, { onOpenModal, TopicResultData } from './commonModal';
+import BrokerModal, {
+  onOpenModal as onOpenBrokerModal,
+} from '@/pages/Broker/commonModal';
+import { BROKER_INFO_ZH_MAP } from '@/constants/broker';
+import { PERSON_INFO_ZH_MAP } from '@/constants/person';
+import { TOPIC_INFO_ZH_MAP } from '@/constants/topic';
 
 declare type TopicQueryData = {
   topicName: string;
@@ -30,28 +32,37 @@ const Detail: React.FC = () => {
   const [isSrvAcceptSubscribe, setIsSrvAcceptSubscribe] = useState<any>(false);
   const [enableAuthControl, setEnableAuthControl] = useState<any>(false);
   const [filterData, updateFilterData] = useImmer<any>({});
-  const queryTopicInfo = useRequest<any>((data: TopicQueryData = {
-    topicName: name,
-  }) => ({
-    url: '/api/op_query/admin_query_topic_authorize_control',
-    data: {
-      ...data
-    }
-  }));
-  const queryTopicConf = useRequest<any>((data: TopicQueryData = {
-    topicName: name,
-  }) => ({
-    url: '/api/op_query/admin_query_topic_info',
-    data: {
-      ...data
-    }
-  }), {
-    onSuccess: data => {
-      setIsSrvAcceptPublish(data[0]['isSrvAcceptPublish']);
-      setIsSrvAcceptSubscribe(data[0]['isSrvAcceptSubscribe']);
-      setEnableAuthControl(data[0]['authData']['enableAuthControl']);
+  const queryTopicInfo = useRequest<any>(
+    (
+      data: TopicQueryData = {
+        topicName: name,
+      }
+    ) => ({
+      url: '/api/op_query/admin_query_topic_authorize_control',
+      data: {
+        ...data,
+      },
+    })
+  );
+  const queryTopicConf = useRequest<any>(
+    (
+      data: TopicQueryData = {
+        topicName: name,
+      }
+    ) => ({
+      url: '/api/op_query/admin_query_topic_info',
+      data: {
+        ...data,
+      },
+    }),
+    {
+      onSuccess: data => {
+        setIsSrvAcceptPublish(data[0]['isSrvAcceptPublish']);
+        setIsSrvAcceptSubscribe(data[0]['isSrvAcceptSubscribe']);
+        setEnableAuthControl(data[0]['authData']['enableAuthControl']);
+      },
     }
-  });
+  );
 
   // render
   const searchStyle = {
@@ -59,31 +70,44 @@ const Detail: React.FC = () => {
     top: '-40px',
     right: '10px',
     zIndex: 1,
-    width: '300px'
+    width: '300px',
   };
   const renderBrokerList = (): ReactNode => {
-    const columns = [{
+    const columns = [
+      {
         title: 'Broker',
         render: (t: string, r: TopicResultData) => {
           return `${r.brokerId}#${r.brokerIp}:${r.brokerPort}`;
         },
       },
       {
-        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'runInfo.acceptPublish'),
+        title: transParamsWithConstantsMap(
+          BROKER_INFO_ZH_MAP,
+          'runInfo.acceptPublish'
+        ),
         dataIndex: ['runInfo', 'acceptPublish'],
         render: (t: string) => boolean2Chinese(t),
       },
       {
-        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'runInfo.acceptSubscribe'),
+        title: transParamsWithConstantsMap(
+          BROKER_INFO_ZH_MAP,
+          'runInfo.acceptSubscribe'
+        ),
         dataIndex: ['runInfo', 'acceptSubscribe'],
         render: (t: string) => boolean2Chinese(t),
       },
       {
-        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'runInfo.numPartitions'),
+        title: transParamsWithConstantsMap(
+          BROKER_INFO_ZH_MAP,
+          'runInfo.numPartitions'
+        ),
         dataIndex: ['runInfo', 'numPartitions'],
       },
       {
-        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'runInfo.brokerManageStatus'),
+        title: transParamsWithConstantsMap(
+          BROKER_INFO_ZH_MAP,
+          'runInfo.brokerManageStatus'
+        ),
         dataIndex: ['runInfo', 'brokerManageStatus'],
       },
       {
@@ -92,7 +116,10 @@ const Detail: React.FC = () => {
         render: (t: string) => boolean2Chinese(t),
       },
       {
-        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'acceptSubscribe'),
+        title: transParamsWithConstantsMap(
+          BROKER_INFO_ZH_MAP,
+          'acceptSubscribe'
+        ),
         dataIndex: 'acceptSubscribe',
         render: (t: string) => boolean2Chinese(t),
       },
@@ -101,11 +128,17 @@ const Detail: React.FC = () => {
         dataIndex: 'numPartitions',
       },
       {
-        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'unflushThreshold'),
+        title: transParamsWithConstantsMap(
+          BROKER_INFO_ZH_MAP,
+          'unflushThreshold'
+        ),
         dataIndex: 'unflushThreshold',
       },
       {
-        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'unflushInterval'),
+        title: transParamsWithConstantsMap(
+          BROKER_INFO_ZH_MAP,
+          'unflushInterval'
+        ),
         dataIndex: 'unflushInterval',
       },
       {
@@ -118,87 +151,96 @@ const Detail: React.FC = () => {
       },
       {
         title: '操作',
-        render: (t:string, r: TopicResultData) => {
-          return (<span>
-            <a onClick={() => onEdit(r)}>编辑</a>
-            <a onClick={() => onReload(r)}>重载</a>
-            <a onClick={() => onDeleteBroker(r)}>删除</a>
-          </span>)
-        }
-      }];
-    const {data} = queryTopicConf;
-    if(!data || !data[0]) return null;
-    const {topicInfo} = data[0];
+        render: (t: string, r: TopicResultData) => {
+          return (
+            <span>
+              <a onClick={() => onEdit(r)}>编辑</a>
+              <a onClick={() => onReload(r)}>重载</a>
+              <a onClick={() => onDeleteBroker(r)}>删除</a>
+            </span>
+          );
+        },
+      },
+    ];
+    const { data } = queryTopicConf;
+    if (!data || !data[0]) return null;
+    const { topicInfo } = data[0];
 
-    return <Table columns={columns}
-                  dataSource={topicInfo}
-                  rowKey={r => `${r.brokerId}#${r.brokerIp}:${r.brokerPort}`}
-                  dataSourceX={filterData.topicInfoList}
-                  searchPlaceholder="请输入brokerId,Ip,Port搜索"
-                  searchStyle={searchStyle}
-                  filterFnX={value =>
-                    tableFilterHelper({
-                      key: value,
-                      srcArray: topicInfo,
-                      targetArray: filterData.topicInfoList,
-                      updateFunction: res =>
-                        updateFilterData(filterData => {
-                          filterData.topicInfoList = res;
-                        }),
-                      filterList: [
-                        'brokerId',
-                        'brokerIp',
-                        'brokerPort'
-                      ],
-                    })
-                  }
-    />;
-  }
+    return (
+      <Table
+        columns={columns}
+        dataSource={topicInfo}
+        rowKey={r => `${r.brokerId}#${r.brokerIp}:${r.brokerPort}`}
+        dataSourceX={filterData.topicInfoList}
+        searchPlaceholder="请输入brokerId,Ip,Port搜索"
+        searchStyle={searchStyle}
+        filterFnX={value =>
+          tableFilterHelper({
+            key: value,
+            srcArray: topicInfo,
+            targetArray: filterData.topicInfoList,
+            updateFunction: res =>
+              updateFilterData(filterData => {
+                filterData.topicInfoList = res;
+              }),
+            filterList: ['brokerId', 'brokerIp', 'brokerPort'],
+          })
+        }
+      />
+    );
+  };
   const renderConsumeGroupList = (): ReactNode => {
-    const columns = [{
+    const columns = [
+      {
         title: '消费组',
         dataIndex: 'groupName',
-      }, {
+      },
+      {
         title: transParamsWithConstantsMap(PERSON_INFO_ZH_MAP, 'createUser'),
         dataIndex: 'createUser',
-      }, {
+      },
+      {
         title: transParamsWithConstantsMap(PERSON_INFO_ZH_MAP, 'createDate'),
         dataIndex: 'createDate',
       },
       {
         title: '操作',
-        render: (t:string, r: TopicResultData) => {
-          return (<span>
-            <a onClick={() => onDeleteConsumeGroup(r)}>删除</a>
-          </span>)
-        }
-      }];
-    const {data} = queryTopicInfo;
-    if(!data || !data[0]) return null;
-    const {authConsumeGroup} = data[0];
+        render: (t: string, r: TopicResultData) => {
+          return (
+            <span>
+              <a onClick={() => onDeleteConsumeGroup(r)}>删除</a>
+            </span>
+          );
+        },
+      },
+    ];
+    const { data } = queryTopicInfo;
+    if (!data || !data[0]) return null;
+    const { authConsumeGroup } = data[0];
 
-    return <Table columns={columns}
-                  dataSource={authConsumeGroup}
-                  rowKey={r => `${r.brokerId}#${r.brokerIp}:${r.brokerPort}`}
-                  dataSourceX={filterData.list}
-                  searchPlaceholder="请输入消费组名称搜索"
-                  searchStyle={searchStyle}
-                  filterFnX={value =>
-                    tableFilterHelper({
-                      key: value,
-                      srcArray: authConsumeGroup,
-                      targetArray: filterData.list,
-                      updateFunction: res =>
-                        updateFilterData(filterData => {
-                          filterData.list = res;
-                        }),
-                      filterList: [
-                        'groupName',
-                      ],
-                    })
-                  }
-    />;
-  }
+    return (
+      <Table
+        columns={columns}
+        dataSource={authConsumeGroup}
+        rowKey={r => `${r.brokerId}#${r.brokerIp}:${r.brokerPort}`}
+        dataSourceX={filterData.list}
+        searchPlaceholder="请输入消费组名称搜索"
+        searchStyle={searchStyle}
+        filterFnX={value =>
+          tableFilterHelper({
+            key: value,
+            srcArray: authConsumeGroup,
+            targetArray: filterData.list,
+            updateFunction: res =>
+              updateFilterData(filterData => {
+                filterData.list = res;
+              }),
+            filterList: ['groupName'],
+          })
+        }
+      />
+    );
+  };
 
   // event
   // isSrvAcceptPublish && isSrvAcceptSubscribe event
@@ -215,32 +257,34 @@ const Detail: React.FC = () => {
       option = e ? '订阅' : '禁止可订阅';
     }
 
-    queryBrokerListByTopicNameQuery.run({
-      data: {
-        topicName,
-        brokerId: ''
-      },
-    }).then((d: TopicResultData) => {
-      onOpenModal({
-        type: 'topicStateChange',
-        title: `请确认操作`,
-        updateFunction: updateModelParams,
-        params: {
-          option,
-          value: e,
+    queryBrokerListByTopicNameQuery
+      .run({
+        data: {
           topicName,
-          data: d[0].topicInfo,
-          type,
-          callback: () => {
-            if (type === 'isSrvAcceptPublish') {
-              setIsSrvAcceptPublish(e);
-            } else if (type === 'isSrvAcceptSubscribe') {
-              setIsSrvAcceptSubscribe(e);
-            }
-          }
+          brokerId: '',
         },
+      })
+      .then((d: TopicResultData) => {
+        onOpenModal({
+          type: 'topicStateChange',
+          title: `请确认操作`,
+          updateFunction: updateModelParams,
+          params: {
+            option,
+            value: e,
+            topicName,
+            data: d[0].topicInfo,
+            type,
+            callback: () => {
+              if (type === 'isSrvAcceptPublish') {
+                setIsSrvAcceptPublish(e);
+              } else if (type === 'isSrvAcceptSubscribe') {
+                setIsSrvAcceptSubscribe(e);
+              }
+            },
+          },
+        });
       });
-    });
   };
   // author
   const onAuthorizeControl = (e: boolean) => {
@@ -256,29 +300,38 @@ const Detail: React.FC = () => {
         topicName,
         callback: () => {
           setEnableAuthControl(e);
-        }
+        },
       },
     });
-  }
+  };
   // edit topic
   const onEdit = (r?: TopicResultData) => {
-    const p = r || queryTopicConf.data[0].topicInfo[0]
+    const p = r || queryTopicConf.data[0].topicInfo[0];
     onOpenModal({
-      type: 'editTopic', title: '编辑Topic', updateFunction: updateModelParams, params: {
+      type: 'editTopic',
+      title: '编辑Topic',
+      updateFunction: updateModelParams,
+      params: {
         ...p,
         callback: (d: any) => {
           onOpenModal({
-            type: 'chooseBroker', title: '选择【修改】broker列表', updateFunction: updateModelParams, params: {
+            type: 'chooseBroker',
+            title: '选择【修改】broker列表',
+            updateFunction: updateModelParams,
+            params: {
               data: d,
               subType: 'edit',
               callback: () => {
-                onOpenModal({type: 'close', updateFunction: updateModelParams})
+                onOpenModal({
+                  type: 'close',
+                  updateFunction: updateModelParams,
+                });
               },
-            }
+            },
           });
-        }
-      }
-    })
+        },
+      },
+    });
   };
   // reload topic
   const queryBrokerInfo = useRequest<any, any>(
@@ -286,38 +339,42 @@ const Detail: React.FC = () => {
     { manual: true }
   );
   const onReload = (r: TopicResultData) => {
-    queryBrokerInfo.run({
-      data: {
-        brokerId: r.brokerId
-      }
-    }).then(data => {
-      onOpenBrokerModal({
-        type: 'reload',
-        title: `确认进行【重载】操作?`,
-        updateFunction: updateBrokerModalParams,
-        params: [data[0].brokerId],
+    queryBrokerInfo
+      .run({
+        data: {
+          brokerId: r.brokerId,
+        },
+      })
+      .then(data => {
+        onOpenBrokerModal({
+          type: 'reload',
+          title: `确认进行【重载】操作?`,
+          updateFunction: updateBrokerModalParams,
+          params: [data[0].brokerId],
+        });
       });
-    })
-  }
+  };
   // on delete broker
   const onDeleteBroker = (r: TopicResultData) => {
-    queryBrokerListByTopicNameQuery.run({
-      data: {
-        topicName: r.topicName,
-        brokerId: r.brokerId
-      },
-    }).then((d: TopicResultData) => {
-      onOpenModal({
-        type: 'deleteTopic',
-        title: `请确认操作`,
-        updateFunction: updateModelParams,
-        params: {
+    queryBrokerListByTopicNameQuery
+      .run({
+        data: {
           topicName: r.topicName,
-          data: d[0].topicInfo,
+          brokerId: r.brokerId,
         },
+      })
+      .then((d: TopicResultData) => {
+        onOpenModal({
+          type: 'deleteTopic',
+          title: `请确认操作`,
+          updateFunction: updateModelParams,
+          params: {
+            topicName: r.topicName,
+            data: d[0].topicInfo,
+          },
+        });
       });
-    });
-  }
+  };
   const onDeleteConsumeGroup = (r: TopicResultData) => {
     onOpenModal({
       type: 'deleteConsumeGroup',
@@ -325,10 +382,10 @@ const Detail: React.FC = () => {
       updateFunction: updateModelParams,
       params: {
         topicName: r.topicName,
-        groupName: r.groupName
+        groupName: r.groupName,
       },
     });
-  }
+  };
 
   return (
     <Spin spinning={queryTopicConf.loading && queryTopicInfo.loading}>
@@ -337,74 +394,115 @@ const Detail: React.FC = () => {
         appendParams={`Topic(${name})详情`}
       />
       <div className="main-container">
-        <TitleWrap title="基本信息" wrapperStyle={{position: 'relative'}} hasSplit={false}>
+        <TitleWrap
+          title="基本信息"
+          wrapperStyle={{ position: 'relative' }}
+          hasSplit={false}
+        >
           <div className="topic-detail-options-wrapper">
             <Switch
               className="mr10"
-              checked={isSrvAcceptPublish} checkedChildren="订阅" unCheckedChildren="订阅"
+              checked={isSrvAcceptPublish}
+              checkedChildren="订阅"
+              unCheckedChildren="订阅"
               onChange={e => onSwitchChange(e, 'isSrvAcceptPublish')}
             />
             <Switch
               className="mr10"
-              checked={isSrvAcceptSubscribe} checkedChildren="发布" unCheckedChildren="发布"
+              checked={isSrvAcceptSubscribe}
+              checkedChildren="发布"
+              unCheckedChildren="发布"
               onChange={e => onSwitchChange(e, 'isSrvAcceptSubscribe')}
             />
             <Switch
               className="mr10"
-              checked={enableAuthControl} checkedChildren="权限可控" unCheckedChildren="权限可控"
+              checked={enableAuthControl}
+              checkedChildren="权限可控"
+              unCheckedChildren="权限可控"
               onChange={e => onAuthorizeControl(e)}
             />
           </div>
           <Form form={form}>
             <Row gutter={24}>
-              {queryTopicConf.data && Object.keys(queryTopicConf.data[0]).map((t: string, index: number) => {
-                const label = transParamsWithConstantsMap(TOPIC_INFO_ZH_MAP, t);
-                const ignoreList = ['isSrvAcceptPublish', 'isSrvAcceptSubscribe'];
-                if (queryTopicConf.data[0][t] instanceof Object || !label || ignoreList.includes(t)) return null
-                return (<Col span={12} key={'queryTopicConf' + index}>
-                  <Form.Item
-                    labelCol={{span: 12}}
-                    label={label}
-                  >
-                    {queryTopicConf.data[0][t] + ''}
-                  </Form.Item>
-                </Col>)
-              })}
+              {queryTopicConf.data &&
+                Object.keys(queryTopicConf.data[0]).map(
+                  (t: string, index: number) => {
+                    const label = transParamsWithConstantsMap(
+                      TOPIC_INFO_ZH_MAP,
+                      t
+                    );
+                    const ignoreList = [
+                      'isSrvAcceptPublish',
+                      'isSrvAcceptSubscribe',
+                    ];
+                    if (
+                      queryTopicConf.data[0][t] instanceof Object ||
+                      !label ||
+                      ignoreList.includes(t)
+                    )
+                      return null;
+                    return (
+                      <Col span={12} key={'queryTopicConf' + index}>
+                        <Form.Item labelCol={{ span: 12 }} label={label}>
+                          {queryTopicConf.data[0][t] + ''}
+                        </Form.Item>
+                      </Col>
+                    );
+                  }
+                )}
             </Row>
           </Form>
         </TitleWrap>
-        <TitleWrap title="缺省配置" wrapperStyle={{position: 'relative'}}>
+        <TitleWrap title="缺省配置" wrapperStyle={{ position: 'relative' }}>
           <div className="topic-detail-options-wrapper">
-            <Button className="mr10" type="primary" size="small" onClick={() => onEdit()}>
+            <Button
+              className="mr10"
+              type="primary"
+              size="small"
+              onClick={() => onEdit()}
+            >
               编辑
             </Button>
           </div>
           <Form form={form}>
             <Row gutter={24}>
-              {['acceptPublish', 'acceptSubscribe', 'unflushThreshold', 'unflushInterval', 'deleteWhen', 'deletePolicy', 'numPartitions'].map((t: string, index: number) => {
-                if(!queryTopicConf.data || !queryTopicConf.data[0].topicInfo[0]) return null;
+              {[
+                'acceptPublish',
+                'acceptSubscribe',
+                'unflushThreshold',
+                'unflushInterval',
+                'deleteWhen',
+                'deletePolicy',
+                'numPartitions',
+              ].map((t: string, index: number) => {
+                if (
+                  !queryTopicConf.data ||
+                  !queryTopicConf.data[0].topicInfo[0]
+                )
+                  return null;
                 const value = queryTopicConf.data[0].topicInfo[0][t];
-                return (<Col span={12} key={'queryTopicConf' + index}>
-                  <Form.Item
-                    labelCol={{span: 12}}
-                    label={t}
-                  >
-                    {value + ''}
-                  </Form.Item>
-                </Col>)
+                return (
+                  <Col span={12} key={'queryTopicConf' + index}>
+                    <Form.Item labelCol={{ span: 12 }} label={t}>
+                      {value + ''}
+                    </Form.Item>
+                  </Col>
+                );
               })}
             </Row>
           </Form>
         </TitleWrap>
-        <TitleWrap title="部署Broker列表">
-          {renderBrokerList()}
-        </TitleWrap>
-        <TitleWrap title="消费组列表">
-          {renderConsumeGroupList()}
-        </TitleWrap>
+        <TitleWrap title="部署Broker列表">{renderBrokerList()}</TitleWrap>
+        <TitleWrap title="消费组列表">{renderConsumeGroupList()}</TitleWrap>
       </div>
-      <CommonModal modalParams={modalParams} data={[queryTopicConf.data && queryTopicConf.data[0]]} />
-      <BrokerModal modalParams={brokerModalParams} data={[queryBrokerInfo.data && queryBrokerInfo.data[0]]} />
+      <CommonModal
+        modalParams={modalParams}
+        data={[queryTopicConf.data && queryTopicConf.data[0]]}
+      />
+      <BrokerModal
+        modalParams={brokerModalParams}
+        data={[queryBrokerInfo.data && queryBrokerInfo.data[0]]}
+      />
     </Spin>
   );
 };
diff --git a/web/src/pages/Topic/index.tsx b/web/src/pages/Topic/index.tsx
index d85dc8b..cd112f9 100644
--- a/web/src/pages/Topic/index.tsx
+++ b/web/src/pages/Topic/index.tsx
@@ -2,38 +2,48 @@ import React, { useContext } from 'react';
 import GlobalContext from '@/context/globalContext';
 import Breadcrumb from '@/components/Breadcrumb';
 import Table from '@/components/Tablex';
-import { Form, Button, Spin, Switch} from 'antd';
+import { Form, Button, Spin, Switch } from 'antd';
 import { useImmer } from 'use-immer';
 import { useRequest } from '@/hooks';
 import tableFilterHelper from '@/components/Tablex/tableFilterHelper';
-import { boolean2Chinese, transParamsWithConstantsMap } from '@/utils';
-import {TOPIC_INFO_ZH_MAP} from '@/constants/topic';
+import { transParamsWithConstantsMap } from '@/utils';
+import { TOPIC_INFO_ZH_MAP } from '@/constants/topic';
 import './index.less';
-import {Link} from "react-router-dom";
-import CommonModal, {OPTIONS, onOpenModal, TopicResultData, TopicData} from './commonModal'
+import { Link } from 'react-router-dom';
+import CommonModal, {
+  onOpenModal,
+  TopicResultData,
+  TopicData,
+} from './commonModal';
 
 const Topic: React.FC = () => {
   // column config
   const columns = [
     {
-      title: transParamsWithConstantsMap(TOPIC_INFO_ZH_MAP,'topicName'),
+      title: transParamsWithConstantsMap(TOPIC_INFO_ZH_MAP, 'topicName'),
       dataIndex: 'topicName',
       render: (t: Array<any>) => <Link to={'/topic/' + t}>{t}</Link>,
     },
     {
-      title: transParamsWithConstantsMap(TOPIC_INFO_ZH_MAP,'infoCount'),
+      title: transParamsWithConstantsMap(TOPIC_INFO_ZH_MAP, 'infoCount'),
       dataIndex: 'infoCount',
     },
     {
-      title: transParamsWithConstantsMap(TOPIC_INFO_ZH_MAP,'totalCfgNumPart'),
+      title: transParamsWithConstantsMap(TOPIC_INFO_ZH_MAP, 'totalCfgNumPart'),
       dataIndex: 'totalCfgNumPart',
     },
     {
-      title: transParamsWithConstantsMap(TOPIC_INFO_ZH_MAP,'totalRunNumPartCount'),
+      title: transParamsWithConstantsMap(
+        TOPIC_INFO_ZH_MAP,
+        'totalRunNumPartCount'
+      ),
       dataIndex: 'totalRunNumPartCount',
     },
     {
-      title: transParamsWithConstantsMap(TOPIC_INFO_ZH_MAP,'isSrvAcceptPublish'),
+      title: transParamsWithConstantsMap(
+        TOPIC_INFO_ZH_MAP,
+        'isSrvAcceptPublish'
+      ),
       dataIndex: 'isSrvAcceptPublish',
       render: (t: boolean, r: TopicResultData) => {
         return (
@@ -45,7 +55,10 @@ const Topic: React.FC = () => {
       },
     },
     {
-      title: transParamsWithConstantsMap(TOPIC_INFO_ZH_MAP,'isSrvAcceptSubscribe'),
+      title: transParamsWithConstantsMap(
+        TOPIC_INFO_ZH_MAP,
+        'isSrvAcceptSubscribe'
+      ),
       dataIndex: 'isSrvAcceptSubscribe',
       render: (t: boolean, r: TopicResultData) => {
         return (
@@ -57,7 +70,10 @@ const Topic: React.FC = () => {
       },
     },
     {
-      title: transParamsWithConstantsMap(TOPIC_INFO_ZH_MAP,'enableAuthControl'),
+      title: transParamsWithConstantsMap(
+        TOPIC_INFO_ZH_MAP,
+        'enableAuthControl'
+      ),
       dataIndex: 'authData.enableAuthControl',
       render: (t: boolean, r: TopicResultData) => {
         return (
@@ -72,9 +88,9 @@ const Topic: React.FC = () => {
       title: '操作',
       dataIndex: 'topicIp',
       render: (t: string, r: any) => {
-        return <a onClick={() => onDelete(r)}>删除</a>
-      }
-    }
+        return <a onClick={() => onDelete(r)}>删除</a>;
+      },
+    },
   ];
   const { breadMap } = useContext(GlobalContext);
   const [modalParams, updateModelParams] = useImmer<any>({});
@@ -82,17 +98,20 @@ const Topic: React.FC = () => {
   const [topicList, updateTopicList] = useImmer<TopicData>([]);
   const [form] = Form.useForm();
   // init query
-  const { data, loading, run } = useRequest<any, TopicData>((data: TopicResultData) => ({
-    url: '/api/op_query/admin_query_topic_info',
-    data: data,
-  }), {
-    cacheKey: 'topicList',
-    onSuccess: data => {
-      updateTopicList(d => {
-        Object.assign(d, data);
-      });
-    },
-  });
+  const { data, loading, run } = useRequest<any, TopicData>(
+    (data: TopicResultData) => ({
+      url: '/api/op_query/admin_query_topic_info',
+      data: data,
+    }),
+    {
+      cacheKey: 'topicList',
+      onSuccess: data => {
+        updateTopicList(d => {
+          Object.assign(d, data);
+        });
+      },
+    }
+  );
 
   // table event
   // acceptSubscribe && acceptPublish options
@@ -108,33 +127,35 @@ const Topic: React.FC = () => {
       option = e ? '订阅' : '禁止可订阅';
     }
 
-    queryBrokerListByTopicNameQuery.run({
-      data: {
-        topicName: r.topicName,
-        brokerId: ''
-      },
-    }).then((d: TopicResultData) => {
-      onOpenModal({
-        type: 'topicStateChange',
-        title: `请确认操作`,
-        updateFunction: updateModelParams,
-        params: {
-          option,
-          value: e,
+    queryBrokerListByTopicNameQuery
+      .run({
+        data: {
           topicName: r.topicName,
-          data: d[0].topicInfo,
-          type,
-          callback: () => {
-            const index = data.findIndex(
-              (t: TopicResultData) => t.topicName === r.topicName
-            );
-            updateTopicList(d => {
-              d[index][type] = e + '';
-            });
-          }
+          brokerId: '',
         },
+      })
+      .then((d: TopicResultData) => {
+        onOpenModal({
+          type: 'topicStateChange',
+          title: `请确认操作`,
+          updateFunction: updateModelParams,
+          params: {
+            option,
+            value: e,
+            topicName: r.topicName,
+            data: d[0].topicInfo,
+            type,
+            callback: () => {
+              const index = data.findIndex(
+                (t: TopicResultData) => t.topicName === r.topicName
+              );
+              updateTopicList(d => {
+                d[index][type] = e + '';
+              });
+            },
+          },
+        });
       });
-    });
   };
   // author
   const onAuthorizeControl = (e: boolean, r: TopicResultData) => {
@@ -154,45 +175,56 @@ const Topic: React.FC = () => {
           updateTopicList(d => {
             d[index]['authData']['enableAuthControl'] = e + '';
           });
-        }
+        },
       },
     });
-  }
+  };
   // new topic
   const onNewTopic = () => {
     onOpenModal({
-      type: 'newTopic', title: '新建Topic', updateFunction: updateModelParams, params: {
+      type: 'newTopic',
+      title: '新建Topic',
+      updateFunction: updateModelParams,
+      params: {
         callback: (d: any) => {
           onOpenModal({
-            type: 'chooseBroker', title: '选择【新增】broker列表', updateFunction: updateModelParams, params: {
+            type: 'chooseBroker',
+            title: '选择【新增】broker列表',
+            updateFunction: updateModelParams,
+            params: {
               data: d,
               callback: () => {
-                onOpenModal({type: 'close', updateFunction: updateModelParams})
+                onOpenModal({
+                  type: 'close',
+                  updateFunction: updateModelParams,
+                });
               },
-            }
+            },
           });
-        }
-      }
-    })
+        },
+      },
+    });
   };
   // delete
   const onDelete = (r: TopicResultData) => {
-    queryBrokerListByTopicNameQuery.run({
-      data: {
-        topicName: r.topicName,
-        brokerId: ''
-      },
-    }).then((d: TopicResultData) => {
-      onOpenModal({
-        type: 'deleteTopic',
-        title: `请确认操作`,
-        updateFunction: updateModelParams,
-        params: {
+    queryBrokerListByTopicNameQuery
+      .run({
+        data: {
           topicName: r.topicName,
-          data: d[0].topicInfo,
+          brokerId: '',
         },
+      })
+      .then((d: TopicResultData) => {
+        onOpenModal({
+          type: 'deleteTopic',
+          title: `请确认操作`,
+          updateFunction: updateModelParams,
+          params: {
+            topicName: r.topicName,
+            data: d[0].topicInfo,
+          },
+        });
       });
-    });
   };
 
   return (
@@ -234,9 +266,7 @@ const Topic: React.FC = () => {
                 updateFilterData(filterData => {
                   filterData.list = res;
                 }),
-              filterList: [
-                'topicName',
-              ],
+              filterList: ['topicName'],
             })
           }
         />
diff --git a/web/src/pages/Topic/query.tsx b/web/src/pages/Topic/query.tsx
index fc2a612..bf17545 100644
--- a/web/src/pages/Topic/query.tsx
+++ b/web/src/pages/Topic/query.tsx
@@ -1,9 +1,9 @@
 import * as React from 'react';
 import './index.less';
-import {OKProps} from "@/components/Modalx";
-import {useRequest} from "@/hooks";
-import {useContext, useEffect} from "react";
-import GlobalContext from "@/context/globalContext";
+import { OKProps } from '@/components/Modalx';
+import { useRequest } from '@/hooks';
+import { useContext, useEffect } from 'react';
+import GlobalContext from '@/context/globalContext';
 
 interface ComProps {
   fire: string;
@@ -11,18 +11,19 @@ interface ComProps {
   type: string;
 }
 
-let newObjectTemp: string = '';
-let editObjectTemp: string = '';
+let newObjectTemp = '';
+let editObjectTemp = '';
 const Comp = (props: ComProps) => {
-  const {fire} = props;
+  const { fire } = props;
   const { userInfo } = useContext(GlobalContext);
+  // eslint-disable-next-line
   useEffect(() => {
-    const {params, type} = props;
+    const { params, type } = props;
     dispatchAction(type, params);
   }, [fire]);
 
   const dispatchAction = (type: string, p: OKProps) => {
-    if(!fire) return null;
+    if (!fire) return null;
     let promise;
     switch (type) {
       case 'newTopic':
@@ -51,17 +52,20 @@ const Comp = (props: ComProps) => {
         break;
     }
 
-    promise && promise.then(t => {
-      const {callback} = p.params;
-      if(t.statusCode !== 0 && callback) callback(t);
-    })
+    promise &&
+      promise.then(t => {
+        const { callback } = p.params;
+        if (t.statusCode !== 0 && callback) callback(t);
+      });
   };
-  const commonQuery = useRequest<any, any>(
-    (url, data) => ({ url, ...data }),
-    { manual: true }
-  );
+  const commonQuery = useRequest<any, any>((url, data) => ({ url, ...data }), {
+    manual: true,
+  });
   const newTopicQuery = useRequest<any, any>(
-    data => ({ url: '/api/op_query/admin_query_broker_topic_config_info', ...data }),
+    data => ({
+      url: '/api/op_query/admin_query_broker_topic_config_info',
+      ...data,
+    }),
     { manual: true }
   );
   const newTopic = (p: OKProps) => {
@@ -69,7 +73,7 @@ const Comp = (props: ComProps) => {
     return newTopicQuery.run({
       data: {
         topicName: '',
-        brokerId: ''
+        brokerId: '',
       },
     });
   };
@@ -80,18 +84,18 @@ const Comp = (props: ComProps) => {
   );
   const endChooseBroker = (p: OKProps) => {
     const topicParams = JSON.parse(newObjectTemp);
-    const {params} = p;
+    const { params } = p;
     return endChooseBrokerQuery.run({
       data: {
         borkerId: params.selectBroker.join(','),
         confModAuthToken: p.psw,
-        ...topicParams
+        ...topicParams,
       },
     });
   };
 
   const editTopic = (p: OKProps) => {
-    const {params} = p;
+    const { params } = p;
     editObjectTemp = JSON.stringify(p.params);
     return newTopicQuery.run({
       data: {
@@ -102,14 +106,14 @@ const Comp = (props: ComProps) => {
   };
   const endEditChooseBroker = (p: OKProps) => {
     const topicParams = JSON.parse(editObjectTemp);
-    const {params} = p;
+    const { params } = p;
     return commonQuery.run(`/api/op_modify/admin_modify_topic_info`, {
       data: {
         borkerId: params.selectBroker.join(','),
         confModAuthToken: p.psw,
-        ...topicParams
+        ...topicParams,
       },
-    })
+    });
   };
 
   const deleteTopic = (type: string, p: OKProps) => {
@@ -119,36 +123,35 @@ const Comp = (props: ComProps) => {
         brokerId: params.selectBroker.join(','),
         confModAuthToken: p.psw,
         modifyUser: userInfo.userName,
-        topicName: params.topicName
+        topicName: params.topicName,
       },
     });
   };
   const deleteConsumeGroup = (type: string, p: OKProps) => {
     const { params } = p;
-    return commonQuery.run(`/api/op_modify/admin_delete_allowed_consumer_group_info`, {
-      data: {
-        groupName: params.groupName,
-        confModAuthToken: p.psw,
-        topicName: params.topicName
-      },
-    });
+    return commonQuery.run(
+      `/api/op_modify/admin_delete_allowed_consumer_group_info`,
+      {
+        data: {
+          groupName: params.groupName,
+          confModAuthToken: p.psw,
+          topicName: params.topicName,
+        },
+      }
+    );
   };
   const topicStateChange = (type: string, p: OKProps) => {
     const { params } = p;
-    let data: {
-      [key: string]: any;
-    };
-
-    data = {
+    const data: any = {
       brokerId: params.selectBroker.join([',']),
       confModAuthToken: p.psw,
       modifyUser: userInfo.userName,
-      topicName: params.topicName
-    }
-    if(params.type === 'isSrvAcceptPublish') {
+      topicName: params.topicName,
+    };
+    if (params.type === 'isSrvAcceptPublish') {
       data.acceptPublish = params.value;
     }
-    if(params.type === 'isSrvAcceptSubscribe') {
+    if (params.type === 'isSrvAcceptSubscribe') {
       data.acceptSubscribe = params.value;
     }
 
@@ -159,25 +162,19 @@ const Comp = (props: ComProps) => {
 
   const authorizeControl = (type: string, p: OKProps) => {
     const { params } = p;
-    let data: {
-      [key: string]: any;
-    };
-
-    data = {
+    const data: any = {
       confModAuthToken: p.psw,
       topicName: params.topicName,
       isEnable: params.value,
       modifyUser: userInfo.userName,
-    }
+    };
 
     return commonQuery.run(`/api/op_modify/admin_set_topic_authorize_control`, {
       data,
     });
   };
 
-  return (
-    <></>
-  );
+  return <></>;
 };
 
 export default Comp;
diff --git a/web/src/router.tsx b/web/src/router.tsx
index 66e0cdc..46df97d 100644
--- a/web/src/router.tsx
+++ b/web/src/router.tsx
@@ -14,6 +14,7 @@ import GlobalContext from '@/context/globalContext';
 const App = () => {
   const [cluster, setCluster] = useState();
   const [breadMap, setBreadMap] = useState();
+  // eslint-disable-next-line
   const [userInfo, setUserInfo] = useState({
     userName: 'webapi',
   });
diff --git a/web/src/utils/index.ts b/web/src/utils/index.ts
index d741565..e410d91 100644
--- a/web/src/utils/index.ts
+++ b/web/src/utils/index.ts
@@ -1,7 +1,7 @@
 import { isObject, isEmpty } from 'lodash';
 
 export const isDevelopEnv = () => {
-  return process.env.NODE_ENV === 'development'
+  return process.env.NODE_ENV === 'development';
 };
 
 export const isEmptyParam = (value: any): boolean => {
@@ -37,6 +37,9 @@ export const boolean2Chinese = (value: boolean | string): string => {
   return !v ? '否' : '是';
 };
 
-export const transParamsWithConstantsMap = (map: any, paramsName: string): string => {
+export const transParamsWithConstantsMap = (
+  map: any,
+  paramsName: string
+): string => {
   return map[paramsName] || paramsName;
-}
+};

[incubator-inlong] 02/10: feat(issue): issue completed

Posted by do...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dockerzhang pushed a commit to branch new-web-client
in repository https://gitbox.apache.org/repos/asf/incubator-inlong.git

commit 84931199b839fa9a9e26190f02932e5a3c1e4abf
Author: zakwu <12...@qq.com>
AuthorDate: Tue Jun 16 18:14:07 2020 +0800

    feat(issue): issue completed
---
 web/package-lock.json                      | 26 ++++----
 web/package.json                           |  4 +-
 web/src/components/Breadcrumb/index.tsx    | 11 +++-
 web/src/components/Layout/index.less       | 10 ++++
 web/src/configs/menus/index.tsx            |  7 +++
 web/src/hooks/index.ts                     | 38 +++++++++++-
 web/src/pages/Issue/consumeGroupDetail.tsx | 95 ++++++++++++++++++++++++++++++
 web/src/pages/Issue/index.less             |  2 -
 web/src/pages/Issue/index.tsx              | 90 ++++++++++++++++++++++++++--
 web/src/router.tsx                         | 12 +++-
 web/src/routes/index.tsx                   |  5 +-
 web/src/setupProxy.js                      |  5 +-
 12 files changed, 282 insertions(+), 23 deletions(-)

diff --git a/web/package-lock.json b/web/package-lock.json
index 8eba5d6..9ee94d4 100644
--- a/web/package-lock.json
+++ b/web/package-lock.json
@@ -2812,8 +2812,8 @@
     },
     "@umijs/use-request": {
       "version": "1.4.3",
-      "resolved": "https://registry.npmjs.org/@umijs/use-request/-/use-request-1.4.3.tgz",
-      "integrity": "sha512-aH4GCdRnMCaaciygdN0KtCDQdBBh1KyiNUAgYDPX8Y4brmbymEpJViX1FU4isOTbV34WlbkWTiBpR9HIi2ciNQ==",
+      "resolved": "http://r.tnpm.oa.com/@umijs/use-request/download/@umijs/use-request-1.4.3.tgz",
+      "integrity": "sha1-vF+txMsH15brNfCYONahXLEoAvc=",
       "requires": {
         "lodash.debounce": "^4.0.8",
         "lodash.throttle": "^4.1.1",
@@ -6548,7 +6548,7 @@
     },
     "encoding": {
       "version": "0.1.12",
-      "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
+      "resolved": "http://r.tnpm.oa.com/encoding/download/encoding-0.1.12.tgz",
       "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
       "requires": {
         "iconv-lite": "~0.4.13"
@@ -9795,7 +9795,7 @@
     },
     "isomorphic-fetch": {
       "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
+      "resolved": "http://r.tnpm.oa.com/isomorphic-fetch/download/isomorphic-fetch-2.2.1.tgz",
       "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
       "requires": {
         "node-fetch": "^1.0.1",
@@ -11172,7 +11172,7 @@
     },
     "lodash.debounce": {
       "version": "4.0.8",
-      "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+      "resolved": "http://r.tnpm.oa.com/lodash.debounce/download/lodash.debounce-4.0.8.tgz",
       "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
     },
     "lodash.flow": {
@@ -11225,7 +11225,7 @@
     },
     "lodash.throttle": {
       "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
+      "resolved": "http://r.tnpm.oa.com/lodash.throttle/download/lodash.throttle-4.1.1.tgz",
       "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ="
     },
     "lodash.uniq": {
@@ -12259,8 +12259,8 @@
     },
     "node-fetch": {
       "version": "1.7.3",
-      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
-      "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
+      "resolved": "http://r.tnpm.oa.com/node-fetch/download/node-fetch-1.7.3.tgz",
+      "integrity": "sha1-mA9vcthSEaU0fGsrwYxbhMPrR+8=",
       "requires": {
         "encoding": "^0.1.11",
         "is-stream": "^1.0.1"
@@ -18628,8 +18628,8 @@
     },
     "umi-request": {
       "version": "1.3.3",
-      "resolved": "https://registry.npmjs.org/umi-request/-/umi-request-1.3.3.tgz",
-      "integrity": "sha512-TRf5x11OJ/9VBi2ZzCJGg/ZFs6KXxpZg1hV0/9oYa9d4YZtQ62Gk6djbonYoMFkyw7fMcxRh8ayPe4YG/gCNeg==",
+      "resolved": "http://r.tnpm.oa.com/umi-request/download/umi-request-1.3.3.tgz",
+      "integrity": "sha1-nwU6O798jol2XKjjwBGPHLhIHxE=",
       "requires": {
         "isomorphic-fetch": "^2.2.1",
         "qs": "^6.9.1"
@@ -18940,6 +18940,12 @@
       "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
       "dev": true
     },
+    "use-immer": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/use-immer/-/use-immer-0.4.0.tgz",
+      "integrity": "sha512-mxx4jbRRc1/56geSc3VHx8gg3FvlzUpQPfVNJXtU1NRK/iTdK0pV3k3YPi7iFUcCM8YJ6/0dUBENyuk3WO/gxw==",
+      "dev": true
+    },
     "use-json-comparison": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/use-json-comparison/-/use-json-comparison-1.0.5.tgz",
diff --git a/web/package.json b/web/package.json
index 688553c..5b8fefc 100644
--- a/web/package.json
+++ b/web/package.json
@@ -8,6 +8,7 @@
     "@reactseed/use-redux": "^0.0.3",
     "@reactseed/use-request": "^0.0.2",
     "@types/lodash": "^4.14.155",
+    "@umijs/use-request": "^1.4.3",
     "antd": "^4.2.2",
     "immer": "^6.0.9",
     "lodash": "^4.17.15",
@@ -103,6 +104,7 @@
     "stylelint": "^13.3.3",
     "stylelint-config-prettier": "^8.0.1",
     "stylelint-config-standard": "^20.0.0",
-    "typescript": "~3.8.3"
+    "typescript": "~3.8.3",
+    "use-immer": "^0.4.0"
   }
 }
diff --git a/web/src/components/Breadcrumb/index.tsx b/web/src/components/Breadcrumb/index.tsx
index 3aee452..4d41369 100644
--- a/web/src/components/Breadcrumb/index.tsx
+++ b/web/src/components/Breadcrumb/index.tsx
@@ -7,11 +7,12 @@ import { Breadcrumb } from 'antd';
 
 export interface BreadcrumbProps {
   breadcrumbMap?: Map<string, import('@umijs/route-utils').MenuDataItem>;
+  appendParams?: string;
 }
 
 const BasicLayout: React.FC<BreadcrumbProps> = props => {
   const location = useLocation();
-  const { breadcrumbMap } = props;
+  const { breadcrumbMap, appendParams } = props;
 
   const pathSnippets = location.pathname.split('/').filter(i => i);
   const breadcrumbItems = pathSnippets.map((_, index) => {
@@ -21,6 +22,14 @@ const BasicLayout: React.FC<BreadcrumbProps> = props => {
         breadcrumbNameMap[t.pro_layout_parentKeys.join('/') + t.key] = t.name;
       });
     const url = `/${pathSnippets.slice(0, index + 1).join('/')}`;
+    if (appendParams && index === pathSnippets.length - 1) {
+      return (
+        <Breadcrumb.Item key={url}>
+          <Link to={url}>{appendParams}</Link>
+        </Breadcrumb.Item>
+      );
+    }
+
     return (
       <Breadcrumb.Item key={url}>
         <Link to={url}>{breadcrumbNameMap[url]}</Link>
diff --git a/web/src/components/Layout/index.less b/web/src/components/Layout/index.less
index ef8b6fd..9811a7d 100644
--- a/web/src/components/Layout/index.less
+++ b/web/src/components/Layout/index.less
@@ -9,3 +9,13 @@
 .header-span {
   float: left;
 }
+
+// global css
+.main-container {
+  background: #fff;
+  padding: 20px;
+}
+
+.search-wrapper {
+  margin-bottom: 20px;
+}
\ No newline at end of file
diff --git a/web/src/configs/menus/index.tsx b/web/src/configs/menus/index.tsx
index 9899708..140f583 100644
--- a/web/src/configs/menus/index.tsx
+++ b/web/src/configs/menus/index.tsx
@@ -16,6 +16,13 @@ const menus: Route[] = [
     path: '/issue',
     name: '分发查询',
     icon: <NodeExpandOutlined />,
+    hideChildrenInMenu: true,
+    children: [
+      {
+        path: '/:id',
+        name: '消费组详情',
+      },
+    ],
   },
   {
     name: '配置管理',
diff --git a/web/src/hooks/index.ts b/web/src/hooks/index.ts
index d6bb0cd..6ce8168 100644
--- a/web/src/hooks/index.ts
+++ b/web/src/hooks/index.ts
@@ -1,5 +1,41 @@
 import { useHistory, useLocation } from 'react-router-dom';
-import useRequest from '@reactseed/use-request';
+import useRequest, { axios } from '@reactseed/use-request';
 import useRedux from '@reactseed/use-redux';
+import { message } from 'antd';
 
+interface DataProps {
+  data: any;
+  errorCode: number;
+  errMsg: number;
+  result: boolean;
+}
+// handler for old type interface
+axios.interceptors.request.use(
+  config => {
+    const urlArr = (config.url as any).split('/');
+    config.url = '/webapi.htm';
+    config.params = config.params || {};
+    config.params['type'] = urlArr[2];
+    config.params['method'] = urlArr[3];
+
+    return config;
+  },
+  function(error) {
+    return Promise.reject(error);
+  }
+);
+
+axios.interceptors.response.use(
+  ({ data }) => {
+    if (data.errCode !== 0) {
+      message.error(data.errMsg);
+      return Promise.reject(data);
+    }
+
+    return data || [];
+  },
+  function(error) {
+    return Promise.reject(error);
+  }
+);
 export { useHistory, useLocation, useRequest, useRedux };
diff --git a/web/src/pages/Issue/consumeGroupDetail.tsx b/web/src/pages/Issue/consumeGroupDetail.tsx
new file mode 100644
index 0000000..9e54f42
--- /dev/null
+++ b/web/src/pages/Issue/consumeGroupDetail.tsx
@@ -0,0 +1,95 @@
+import React, { useContext } from 'react';
+import GlobalContext from '@/context/globalContext';
+import Breadcrumb from '@/components/Breadcrumb';
+import Table from '@/components/Tablex';
+import { Form, Input, Button, Spin } from 'antd';
+import { useImmer } from 'use-immer';
+import './index.less';
+import { useRequest } from '@/hooks';
+import { useParams } from 'react-router-dom';
+
+declare type ConsumeGroupData = any[];
+interface ConsumeGroupQueryData {
+  consumeGroup: string;
+}
+
+// column config
+const columns = [
+  {
+    title: '消费者ID',
+    dataIndex: 'consumerId',
+  },
+  {
+    title: '消费Topic',
+    dataIndex: 'topicName',
+  },
+  {
+    title: 'broker地址',
+    dataIndex: 'brokerAddr',
+  },
+  {
+    title: '分区ID',
+    dataIndex: 'partId',
+  },
+];
+
+const queryUser = (data: ConsumeGroupQueryData) => ({
+  url: '/api/op_query/admin_query_consume_group_detail',
+  data: data,
+});
+
+const ConsumeGroupDetail: React.FC = () => {
+  const { id } = useParams();
+  const { breadMap } = useContext(GlobalContext);
+  const [form] = Form.useForm();
+  const [formValues, updateFormValues] = useImmer<any>({});
+  const { data, loading, run } = useRequest<any, ConsumeGroupData>(
+    () =>
+      queryUser({
+        consumeGroup: id,
+      }),
+    {
+      formatResult: data => {
+        const d = data[0];
+        return {
+          list: d.parInfo.map((t: any) => ({
+            consumerId: d.consumerId,
+            ...t,
+          })),
+        };
+      },
+    }
+  );
+
+  const onValuesChange = (p: any) => {
+    updateFormValues(d => {
+      Object.assign(d, p);
+    });
+  };
+  const onSearch = () => {
+    run(formValues);
+  };
+
+  const onReset = () => {
+    form.resetFields();
+    run({});
+  };
+
+  return (
+    <Spin spinning={loading}>
+      <Breadcrumb
+        breadcrumbMap={breadMap}
+        appendParams={`消费组详情(${id})`}
+      ></Breadcrumb>
+      <div className="main-container">
+        <Table
+          columns={columns}
+          dataSource={data?.list}
+          rowKey="brokerAddr"
+        ></Table>
+      </div>
+    </Spin>
+  );
+};
+
+export default ConsumeGroupDetail;
diff --git a/web/src/pages/Issue/index.less b/web/src/pages/Issue/index.less
index c15c7a7..e69de29 100644
--- a/web/src/pages/Issue/index.less
+++ b/web/src/pages/Issue/index.less
@@ -1,2 +0,0 @@
-.home__container {
-}
diff --git a/web/src/pages/Issue/index.tsx b/web/src/pages/Issue/index.tsx
index 3128c5e..bfedf64 100644
--- a/web/src/pages/Issue/index.tsx
+++ b/web/src/pages/Issue/index.tsx
@@ -1,15 +1,97 @@
 import React, { useContext } from 'react';
-import './index.less';
 import GlobalContext from '@/context/globalContext';
 import Breadcrumb from '@/components/Breadcrumb';
+import Table from '@/components/Tablex';
+import { Form, Input, Button, Spin } from 'antd';
+import { useImmer } from 'use-immer';
+import './index.less';
+import { useRequest } from '@/hooks';
+import { Link } from 'react-router-dom';
+
+declare type IssueData = any[];
+interface IssueQueryData {
+  topicName?: string;
+  consumeGroup?: string;
+}
+
+// column config
+const columns = [
+  {
+    title: '消费组',
+    dataIndex: 'consumeGroup',
+    render: (t: Array<any>) => <Link to={'/issue/' + t}>{t}</Link>,
+  },
+  {
+    title: '消费Topic',
+    dataIndex: 'topicSet',
+    render: (t: Array<any>) => {
+      return t.join(',');
+    },
+  },
+  {
+    title: '消费分区',
+    dataIndex: 'consumerNum',
+  },
+];
+
+const queryUser = (data: IssueQueryData) => ({
+  url: '/api/op_query/admin_query_sub_info',
+  data: data,
+});
 
 const Issue: React.FC = () => {
   const { breadMap } = useContext(GlobalContext);
+  const [form] = Form.useForm();
+  const [formValues, updateFormValues] = useImmer<any>({});
+  const { data, loading, run } = useRequest<any, IssueData>(queryUser, {});
+
+  const onValuesChange = (p: any) => {
+    updateFormValues(d => {
+      Object.assign(d, p);
+    });
+  };
+  const onSearch = () => {
+    run(formValues);
+  };
+
+  const onReset = () => {
+    form.resetFields();
+    run({});
+  };
+
   return (
-    <div className="home__container">
+    <Spin spinning={loading}>
       <Breadcrumb breadcrumbMap={breadMap}></Breadcrumb>
-      <div>我打野的</div>
-    </div>
+      <div className="main-container">
+        <div className="search-wrapper">
+          <Form form={form} layout={'inline'} onValuesChange={onValuesChange}>
+            <Form.Item label="Topic 名称" name="topicName">
+              <Input placeholder="" />
+            </Form.Item>
+            <Form.Item label="消费组" name="consumeGroup">
+              <Input placeholder="" />
+            </Form.Item>
+            <Form.Item>
+              <Button
+                type="primary"
+                onClick={onSearch}
+                style={{ margin: '0 20px' }}
+              >
+                查询
+              </Button>
+              <Button type="default" onClick={onReset}>
+                重置
+              </Button>
+            </Form.Item>
+          </Form>
+        </div>
+        <Table
+          columns={columns}
+          dataSource={data}
+          rowKey="consumeGroup"
+        ></Table>
+      </div>
+    </Spin>
   );
 };
 
diff --git a/web/src/router.tsx b/web/src/router.tsx
index eaf2a50..1b6a6e9 100644
--- a/web/src/router.tsx
+++ b/web/src/router.tsx
@@ -1,5 +1,10 @@
 import React, { Suspense, lazy, useState } from 'react';
-import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
+import {
+  BrowserRouter as Router,
+  Switch,
+  Route,
+  Redirect,
+} from 'react-router-dom';
 import { PageLoading } from '@ant-design/pro-layout';
 import { hot } from 'react-hot-loader/root';
 import { Layout } from '@/components';
@@ -31,6 +36,11 @@ const App = () => {
                 />
               ))}
             </Switch>
+            <Route
+              exact
+              path="/"
+              render={() => <Redirect to="/issue" push />}
+            />
           </Suspense>
         </Layout>
       </Router>
diff --git a/web/src/routes/index.tsx b/web/src/routes/index.tsx
index 00a7ce0..032a633 100644
--- a/web/src/routes/index.tsx
+++ b/web/src/routes/index.tsx
@@ -2,9 +2,12 @@ import { RouteProps } from '@/typings';
 
 const routes: RouteProps[] = [
   {
+    path: '/issue/:id',
+    component: () => import('@/pages/Issue/consumeGroupDetail'),
+  },
+  {
     path: '/issue',
     component: () => import('@/pages/Issue'),
-    exact: true,
   },
   {
     path: '/hello',
diff --git a/web/src/setupProxy.js b/web/src/setupProxy.js
index a60f2c8..3496dd6 100644
--- a/web/src/setupProxy.js
+++ b/web/src/setupProxy.js
@@ -3,8 +3,9 @@ const { createProxyMiddleware } = require('http-proxy-middleware');
 
 module.exports = function(app) {
   app.use(
-    createProxyMiddleware('/api', {
-      target: 'https://api.github.com',
+    createProxyMiddleware('/webapi.htm', {
+      // target: 'http://10.224.148.145:8080',
+      target: 'http://10.215.131.92:8080',
       changeOrigin: true,
       ws: true,
     })

[incubator-inlong] 06/10: feat(broker):topic detail page complete

Posted by do...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dockerzhang pushed a commit to branch new-web-client
in repository https://gitbox.apache.org/repos/asf/incubator-inlong.git

commit 9cd056f1b90914456f37ff136d1f5f772218f42f
Author: zakwu <12...@qq.com>
AuthorDate: Mon Jun 29 18:09:04 2020 +0800

    feat(broker):topic detail page complete
---
 web/src/components/Layout/index.tsx     |   2 +-
 web/src/components/TitleWrap/index.less |   4 +
 web/src/components/TitleWrap/index.tsx  |   5 +-
 web/src/constants/broker.ts             |   4 +
 web/src/constants/person.ts             |   4 +
 web/src/constants/topic.ts              |   3 +-
 web/src/pages/Broker/commonModal.tsx    |   3 +-
 web/src/pages/Broker/detail.tsx         |   2 +-
 web/src/pages/Broker/index.less         |   2 +-
 web/src/pages/Topic/commonModal.tsx     |  26 +-
 web/src/pages/Topic/detail.tsx          | 413 +++++++++++++++++++++++++++++++-
 web/src/pages/Topic/index.less          |   4 +-
 web/src/pages/Topic/index.tsx           |   1 -
 web/src/pages/Topic/query.tsx           |  64 +++--
 web/src/routes/index.tsx                |   8 +-
 web/src/setupProxy.js                   |   4 +-
 16 files changed, 501 insertions(+), 48 deletions(-)

diff --git a/web/src/components/Layout/index.tsx b/web/src/components/Layout/index.tsx
index 58ebb20..a4a4ddd 100644
--- a/web/src/components/Layout/index.tsx
+++ b/web/src/components/Layout/index.tsx
@@ -38,7 +38,7 @@ const BasicLayout: React.FC = props => {
     <>
       <ProBasicLayout
         title="TubeMQ"
-        logo="logo192.png"
+        logo="/logo192.png"
         menuDataRender={() => menuData}
         menuItemRender={(menuItemProps, defaultDom) => {
           if (menuItemProps.isUrl || !menuItemProps.path) {
diff --git a/web/src/components/TitleWrap/index.less b/web/src/components/TitleWrap/index.less
index c44787f..b64cf1b 100644
--- a/web/src/components/TitleWrap/index.less
+++ b/web/src/components/TitleWrap/index.less
@@ -5,3 +5,7 @@
   margin-bottom: 15px;
   position: relative;
 }
+
+.split-border {
+  border-top: 1px solid #eee;
+}
diff --git a/web/src/components/TitleWrap/index.tsx b/web/src/components/TitleWrap/index.tsx
index bcf125f..cf2c3f3 100644
--- a/web/src/components/TitleWrap/index.tsx
+++ b/web/src/components/TitleWrap/index.tsx
@@ -5,11 +5,14 @@ interface ComProps {
   title: any;
   children?: any;
   wrapperStyle?: any;
+  hasSplit?: boolean;
 }
 
 const Comp = (props: ComProps) => {
+  const {hasSplit = true} = props;
+
   return (
-    <div style={props.wrapperStyle}>
+    <div style={props.wrapperStyle} className={hasSplit ? 'split-border' : ''}>
       <div className="title-wrap-title">{props.title}</div>
       {props.children}
     </div>
diff --git a/web/src/constants/broker.ts b/web/src/constants/broker.ts
index e2b17c6..7270aae 100644
--- a/web/src/constants/broker.ts
+++ b/web/src/constants/broker.ts
@@ -15,4 +15,8 @@ export const BROKER_INFO_ZH_MAP = {
   manageStatus: '管理状态',
   runStatus: '运行状态',
   subStatus: '运行子状态',
+  'runInfo.acceptPublish': 'broker可发布状态',
+  'runInfo.acceptSubscribe': 'broker可订阅状态',
+  'runInfo.numPartitions': 'broker分区数',
+  'runInfo.brokerManageStatus': 'broker运行状态'
 };
\ No newline at end of file
diff --git a/web/src/constants/person.ts b/web/src/constants/person.ts
new file mode 100644
index 0000000..1bd1b98
--- /dev/null
+++ b/web/src/constants/person.ts
@@ -0,0 +1,4 @@
+export const PERSON_INFO_ZH_MAP = {
+  createDate: '创建时间',
+  createUser: '创建人',
+};
\ No newline at end of file
diff --git a/web/src/constants/topic.ts b/web/src/constants/topic.ts
index 2757340..1f1cf9c 100644
--- a/web/src/constants/topic.ts
+++ b/web/src/constants/topic.ts
@@ -1,9 +1,10 @@
 export const TOPIC_INFO_ZH_MAP = {
-  topicName: 'Topic',
+  topicName: 'TopicName',
   infoCount: '配置Broker数',
   totalCfgNumPart: '配置分区数',
   totalRunNumPartCount: '运行分区数',
   isSrvAcceptPublish: '可发布',
   isSrvAcceptSubscribe: '可订阅',
   enableAuthControl: "权限受控",
+  groupCount: '授权消费组'
 };
\ No newline at end of file
diff --git a/web/src/pages/Broker/commonModal.tsx b/web/src/pages/Broker/commonModal.tsx
index 3543ebf..fb113d8 100644
--- a/web/src/pages/Broker/commonModal.tsx
+++ b/web/src/pages/Broker/commonModal.tsx
@@ -227,6 +227,7 @@ export const onOpenModal = (p: BrokerModalProps) => {
       onCancel: () =>
         updateFunction((m: any) => {
           m.visible = false;
+          m.isOk = null;
         }),
     });
   });
@@ -253,7 +254,7 @@ const Comp = (props: ComProps) => {
         {modalParams.type === 'editBroker' && renderEditBroker(modalParams, form)}
         {modalParams.type === 'brokerStateChange' && renderBrokerStateChange(modalParams)}
       </div>
-      <Query fire={modalParams.isOk} params={modalParams.okParams} type={modalParams.type} />
+      <Query fire={modalParams.isOk} params={modalParams.okParams} type={modalParams.query || modalParams.type} />
     </Modal>
   )
 };
diff --git a/web/src/pages/Broker/detail.tsx b/web/src/pages/Broker/detail.tsx
index deb3d30..b622dc7 100644
--- a/web/src/pages/Broker/detail.tsx
+++ b/web/src/pages/Broker/detail.tsx
@@ -237,7 +237,7 @@ const Detail: React.FC = () => {
     <Spin spinning={queryBrokerConf.loading && queryTopicInfo.loading}>
       <Breadcrumb
         breadcrumbMap={breadMap}
-        appendParams={`Broker(${id})`}
+        appendParams={`Broker(${id})详情`}
       />
       <div className="main-container">
         <TitleWrap title="运行状态" wrapperStyle={{position: 'relative'}}>
diff --git a/web/src/pages/Broker/index.less b/web/src/pages/Broker/index.less
index c0e07eb..c95e98d 100644
--- a/web/src/pages/Broker/index.less
+++ b/web/src/pages/Broker/index.less
@@ -1,6 +1,6 @@
 .broker-detail-options-wrapper {
   position: absolute;
-  top: 0;
+  top: 15px;
   right: 0;
 
   .mr10 {
diff --git a/web/src/pages/Topic/commonModal.tsx b/web/src/pages/Topic/commonModal.tsx
index 7b28980..3200060 100644
--- a/web/src/pages/Topic/commonModal.tsx
+++ b/web/src/pages/Topic/commonModal.tsx
@@ -145,20 +145,20 @@ const renderChooseBroker = (modalParams: any) => {
     },
     {
       title: '实例数',
-      dataIndex: 'runInfo.totalTopicStoreNum',
+      dataIndex: ['runInfo', 'numTopicStores'],
     },
     {
       title: '当前运行状态',
-      dataIndex: 'runInfo.brokerManageStatus',
+      dataIndex: ['runInfo', 'brokerManageStatus'],
     },
     {
       title: '可发布',
-      dataIndex: 'runInfo.acceptPublish',
+      dataIndex: ['runInfo', 'acceptPublish'],
       render: (t: string) => boolean2Chinese(t),
     },
     {
       title: '可订阅',
-      dataIndex: 'runInfo.acceptSubscribe',
+      dataIndex: ['runInfo', 'acceptSubscribe'],
       render: (t: string) => boolean2Chinese(t),
     },
   ];
@@ -176,7 +176,7 @@ const renderChooseBroker = (modalParams: any) => {
 };
 const renderEditTopic = (modalParams: any, form: FormProps['form']) => {
   const {params: p} = modalParams;
-  const pickArr = ['numPartitions', 'unflushThreshold', 'unflushInterval', 'deleteWhen', 'deletePolicy', 'acceptPublish', 'acceptSubscribe'];
+  const pickArr = ['topicName', 'numPartitions', 'unflushThreshold', 'unflushInterval', 'deleteWhen', 'deletePolicy', 'acceptPublish', 'acceptSubscribe'];
   let brokerFormArr : Array<{
     name: string;
     defaultValue: string;
@@ -229,6 +229,16 @@ const renderDeleteTopic = (modalParams: any) => {
     </div>
   );
 };
+const renderDeleteConsumeGroup = (modalParams: any) => {
+  const { params } = modalParams;
+
+  return (
+    <div>
+      确认<span className="enhance">删除</span> 以下 :
+      <span className="enhance">({params.groupName})</span> 吗?
+    </div>
+  );
+};
 const renderAuthorizeControlChange = (modalParams: any) => {
   const { params } = modalParams;
 
@@ -251,7 +261,7 @@ export const onOpenModal = (p: TopicModalProps) => {
         updateFunction((m: any) => {
           if(type === 'newTopic' || type === 'editTopic') {
             p.params = Object.assign(f && f.getFieldsValue(), {
-              callback: p.params.callback
+              callback: p.params.callback,
             });
           }
 
@@ -263,7 +273,7 @@ export const onOpenModal = (p: TopicModalProps) => {
 
             // end
             if(type === 'chooseBroker') {
-              m.query = 'endChooseBroker';
+              m.query = p.params.subType === 'edit' ? 'endEditChooseBroker' : 'endChooseBroker';
             }
             p.params = Object.assign({}, p.params, {
               selectBroker
@@ -277,6 +287,7 @@ export const onOpenModal = (p: TopicModalProps) => {
       onCancel: () =>
         updateFunction((m: any) => {
           m.visible = false;
+          m.isOk = null;
         }),
     });
   });
@@ -301,6 +312,7 @@ const Comp = (props: ComProps) => {
         {modalParams.type === 'editTopic' && renderEditTopic(modalParams, form)}
         {modalParams.type === 'topicStateChange' && renderTopicStateChange(modalParams)}
         {modalParams.type === 'deleteTopic' && renderDeleteTopic(modalParams)}
+        {modalParams.type === 'deleteConsumeGroup' && renderDeleteConsumeGroup(modalParams)}
         {modalParams.type === 'authorizeControl' && renderAuthorizeControlChange(modalParams)}
       </div>
      <Query fire={modalParams.isOk} params={modalParams.okParams} type={modalParams.visible && (modalParams.query || modalParams.type)} />
diff --git a/web/src/pages/Topic/detail.tsx b/web/src/pages/Topic/detail.tsx
index 693da49..37cb1e5 100644
--- a/web/src/pages/Topic/detail.tsx
+++ b/web/src/pages/Topic/detail.tsx
@@ -1 +1,412 @@
-export {}
\ No newline at end of file
+import React, {ReactNode, useContext, useState} from 'react';
+import GlobalContext from '@/context/globalContext';
+import Breadcrumb from '@/components/Breadcrumb';
+import Table from '@/components/Tablex';
+import TitleWrap from '@/components/TitleWrap';
+import {Form, Button, Spin, Col, Row, Switch} from 'antd';
+import { useImmer } from 'use-immer';
+import './index.less';
+import { useRequest } from '@/hooks';
+import {useParams} from 'react-router-dom';
+import {boolean2Chinese, transParamsWithConstantsMap} from "@/utils";
+import tableFilterHelper from "@/components/Tablex/tableFilterHelper";
+import CommonModal, {onOpenModal, TopicResultData} from './commonModal';
+import BrokerModal, {BrokerData, BrokerModalProps, onOpenModal as onOpenBrokerModal} from '@/pages/Broker/commonModal';
+import {BROKER_INFO_ZH_MAP} from "@/constants/broker";
+import {PERSON_INFO_ZH_MAP} from "@/constants/person";
+import {TOPIC_INFO_ZH_MAP} from "@/constants/topic";
+
+declare type TopicQueryData = {
+  topicName: string;
+};
+
+const Detail: React.FC = () => {
+  const { name } = useParams();
+  const { breadMap } = useContext(GlobalContext);
+  const [form] = Form.useForm();
+  const [modalParams, updateModelParams] = useImmer<any>({});
+  const [brokerModalParams, updateBrokerModalParams] = useImmer<any>({});
+  const [isSrvAcceptPublish, setIsSrvAcceptPublish] = useState<any>(false);
+  const [isSrvAcceptSubscribe, setIsSrvAcceptSubscribe] = useState<any>(false);
+  const [enableAuthControl, setEnableAuthControl] = useState<any>(false);
+  const [filterData, updateFilterData] = useImmer<any>({});
+  const queryTopicInfo = useRequest<any>((data: TopicQueryData = {
+    topicName: name,
+  }) => ({
+    url: '/api/op_query/admin_query_topic_authorize_control',
+    data: {
+      ...data
+    }
+  }));
+  const queryTopicConf = useRequest<any>((data: TopicQueryData = {
+    topicName: name,
+  }) => ({
+    url: '/api/op_query/admin_query_topic_info',
+    data: {
+      ...data
+    }
+  }), {
+    onSuccess: data => {
+      setIsSrvAcceptPublish(data[0]['isSrvAcceptPublish']);
+      setIsSrvAcceptSubscribe(data[0]['isSrvAcceptSubscribe']);
+      setEnableAuthControl(data[0]['authData']['enableAuthControl']);
+    }
+  });
+
+  // render
+  const searchStyle = {
+    position: 'absolute',
+    top: '-40px',
+    right: '10px',
+    zIndex: 1,
+    width: '300px'
+  };
+  const renderBrokerList = (): ReactNode => {
+    const columns = [{
+        title: 'Broker',
+        render: (t: string, r: TopicResultData) => {
+          return `${r.brokerId}#${r.brokerIp}:${r.brokerPort}`;
+        },
+      },
+      {
+        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'runInfo.acceptPublish'),
+        dataIndex: ['runInfo', 'acceptPublish'],
+        render: (t: string) => boolean2Chinese(t),
+      },
+      {
+        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'runInfo.acceptSubscribe'),
+        dataIndex: ['runInfo', 'acceptSubscribe'],
+        render: (t: string) => boolean2Chinese(t),
+      },
+      {
+        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'runInfo.numPartitions'),
+        dataIndex: ['runInfo', 'numPartitions'],
+      },
+      {
+        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'runInfo.brokerManageStatus'),
+        dataIndex: ['runInfo', 'brokerManageStatus'],
+      },
+      {
+        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'acceptPublish'),
+        dataIndex: 'acceptPublish',
+        render: (t: string) => boolean2Chinese(t),
+      },
+      {
+        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'acceptSubscribe'),
+        dataIndex: 'acceptSubscribe',
+        render: (t: string) => boolean2Chinese(t),
+      },
+      {
+        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'numPartitions'),
+        dataIndex: 'numPartitions',
+      },
+      {
+        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'unflushThreshold'),
+        dataIndex: 'unflushThreshold',
+      },
+      {
+        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'unflushInterval'),
+        dataIndex: 'unflushInterval',
+      },
+      {
+        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'deleteWhen'),
+        dataIndex: 'deleteWhen',
+      },
+      {
+        title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'deletePolicy'),
+        dataIndex: 'deletePolicy',
+      },
+      {
+        title: '操作',
+        render: (t:string, r: TopicResultData) => {
+          return (<span>
+            <a onClick={() => onEdit(r)}>编辑</a>
+            <a onClick={() => onReload(r)}>重载</a>
+            <a onClick={() => onDeleteBroker(r)}>删除</a>
+          </span>)
+        }
+      }];
+    const {data} = queryTopicConf;
+    if(!data || !data[0]) return null;
+    const {topicInfo} = data[0];
+
+    return <Table columns={columns}
+                  dataSource={topicInfo}
+                  rowKey={r => `${r.brokerId}#${r.brokerIp}:${r.brokerPort}`}
+                  dataSourceX={filterData.topicInfoList}
+                  searchPlaceholder="请输入brokerId,Ip,Port搜索"
+                  searchStyle={searchStyle}
+                  filterFnX={value =>
+                    tableFilterHelper({
+                      key: value,
+                      srcArray: topicInfo,
+                      targetArray: filterData.topicInfoList,
+                      updateFunction: res =>
+                        updateFilterData(filterData => {
+                          filterData.topicInfoList = res;
+                        }),
+                      filterList: [
+                        'brokerId',
+                        'brokerIp',
+                        'brokerPort'
+                      ],
+                    })
+                  }
+    />;
+  }
+  const renderConsumeGroupList = (): ReactNode => {
+    const columns = [{
+        title: '消费组',
+        dataIndex: 'groupName',
+      }, {
+        title: transParamsWithConstantsMap(PERSON_INFO_ZH_MAP, 'createUser'),
+        dataIndex: 'createUser',
+      }, {
+        title: transParamsWithConstantsMap(PERSON_INFO_ZH_MAP, 'createDate'),
+        dataIndex: 'createDate',
+      },
+      {
+        title: '操作',
+        render: (t:string, r: TopicResultData) => {
+          return (<span>
+            <a onClick={() => onDeleteConsumeGroup(r)}>删除</a>
+          </span>)
+        }
+      }];
+    const {data} = queryTopicInfo;
+    if(!data || !data[0]) return null;
+    const {authConsumeGroup} = data[0];
+
+    return <Table columns={columns}
+                  dataSource={authConsumeGroup}
+                  rowKey={r => `${r.brokerId}#${r.brokerIp}:${r.brokerPort}`}
+                  dataSourceX={filterData.list}
+                  searchPlaceholder="请输入消费组名称搜索"
+                  searchStyle={searchStyle}
+                  filterFnX={value =>
+                    tableFilterHelper({
+                      key: value,
+                      srcArray: authConsumeGroup,
+                      targetArray: filterData.list,
+                      updateFunction: res =>
+                        updateFilterData(filterData => {
+                          filterData.list = res;
+                        }),
+                      filterList: [
+                        'groupName',
+                      ],
+                    })
+                  }
+    />;
+  }
+
+  // event
+  // isSrvAcceptPublish && isSrvAcceptSubscribe event
+  const queryBrokerListByTopicNameQuery = useRequest<any, any>(
+    data => ({ url: '/api/op_query/admin_query_topic_info', ...data }),
+    { manual: true }
+  );
+  const onSwitchChange = (e: boolean, type: string) => {
+    let option = '';
+    const topicName = queryTopicConf.data[0].topicInfo[0].topicName;
+    if (type === 'isSrvAcceptPublish') {
+      option = e ? '发布' : '禁止可发布';
+    } else if (type === 'isSrvAcceptSubscribe') {
+      option = e ? '订阅' : '禁止可订阅';
+    }
+
+    queryBrokerListByTopicNameQuery.run({
+      data: {
+        topicName,
+        brokerId: ''
+      },
+    }).then((d: TopicResultData) => {
+      onOpenModal({
+        type: 'topicStateChange',
+        title: `请确认操作`,
+        updateFunction: updateModelParams,
+        params: {
+          option,
+          value: e,
+          topicName,
+          data: d[0].topicInfo,
+          type,
+          callback: () => {
+            if (type === 'isSrvAcceptPublish') {
+              setIsSrvAcceptPublish(e);
+            } else if (type === 'isSrvAcceptSubscribe') {
+              setIsSrvAcceptSubscribe(e);
+            }
+          }
+        },
+      });
+    });
+  };
+  // author
+  const onAuthorizeControl = (e: boolean) => {
+    const option = e ? '发布' : '禁止可发布';
+    const topicName = queryTopicConf.data[0].topicInfo[0].topicName;
+    onOpenModal({
+      type: 'authorizeControl',
+      title: `请确认操作`,
+      updateFunction: updateModelParams,
+      params: {
+        option,
+        value: e,
+        topicName,
+        callback: () => {
+          setEnableAuthControl(e);
+        }
+      },
+    });
+  }
+  // edit topic
+  const onEdit = (r?: TopicResultData) => {
+    const p = r || queryTopicConf.data[0].topicInfo[0]
+    onOpenModal({
+      type: 'editTopic', title: '编辑Topic', updateFunction: updateModelParams, params: {
+        ...p,
+        callback: (d: any) => {
+          onOpenModal({
+            type: 'chooseBroker', title: '选择【修改】broker列表', updateFunction: updateModelParams, params: {
+              data: d,
+              subType: 'edit',
+              callback: () => {
+                onOpenModal({type: 'close', updateFunction: updateModelParams})
+              },
+            }
+          });
+        }
+      }
+    })
+  };
+  // reload topic
+  const queryBrokerInfo = useRequest<any, any>(
+    data => ({ url: '/api/op_query/admin_query_broker_run_status', ...data }),
+    { manual: true }
+  );
+  const onReload = (r: TopicResultData) => {
+    queryBrokerInfo.run({
+      data: {
+        brokerId: r.brokerId
+      }
+    }).then(data => {
+      onOpenBrokerModal({
+        type: 'reload',
+        title: `确认进行【重载】操作?`,
+        updateFunction: updateBrokerModalParams,
+        params: [data[0].brokerId],
+      });
+    })
+  }
+  // on delete broker
+  const onDeleteBroker = (r: TopicResultData) => {
+    queryBrokerListByTopicNameQuery.run({
+      data: {
+        topicName: r.topicName,
+        brokerId: r.brokerId
+      },
+    }).then((d: TopicResultData) => {
+      onOpenModal({
+        type: 'deleteTopic',
+        title: `请确认操作`,
+        updateFunction: updateModelParams,
+        params: {
+          topicName: r.topicName,
+          data: d[0].topicInfo,
+        },
+      });
+    });
+  }
+  const onDeleteConsumeGroup = (r: TopicResultData) => {
+    onOpenModal({
+      type: 'deleteConsumeGroup',
+      title: `请确认消费组`,
+      updateFunction: updateModelParams,
+      params: {
+        topicName: r.topicName,
+        groupName: r.groupName
+      },
+    });
+  }
+
+  return (
+    <Spin spinning={queryTopicConf.loading && queryTopicInfo.loading}>
+      <Breadcrumb
+        breadcrumbMap={breadMap}
+        appendParams={`Topic(${name})详情`}
+      />
+      <div className="main-container">
+        <TitleWrap title="基本信息" wrapperStyle={{position: 'relative'}} hasSplit={false}>
+          <div className="topic-detail-options-wrapper">
+            <Switch
+              className="mr10"
+              checked={isSrvAcceptPublish} checkedChildren="订阅" unCheckedChildren="订阅"
+              onChange={e => onSwitchChange(e, 'isSrvAcceptPublish')}
+            />
+            <Switch
+              className="mr10"
+              checked={isSrvAcceptSubscribe} checkedChildren="发布" unCheckedChildren="发布"
+              onChange={e => onSwitchChange(e, 'isSrvAcceptSubscribe')}
+            />
+            <Switch
+              className="mr10"
+              checked={enableAuthControl} checkedChildren="权限可控" unCheckedChildren="权限可控"
+              onChange={e => onAuthorizeControl(e)}
+            />
+          </div>
+          <Form form={form}>
+            <Row gutter={24}>
+              {queryTopicConf.data && Object.keys(queryTopicConf.data[0]).map((t: string, index: number) => {
+                const label = transParamsWithConstantsMap(TOPIC_INFO_ZH_MAP, t);
+                const ignoreList = ['isSrvAcceptPublish', 'isSrvAcceptSubscribe'];
+                if (queryTopicConf.data[0][t] instanceof Object || !label || ignoreList.includes(t)) return null
+                return (<Col span={12} key={'queryTopicConf' + index}>
+                  <Form.Item
+                    labelCol={{span: 12}}
+                    label={label}
+                  >
+                    {queryTopicConf.data[0][t] + ''}
+                  </Form.Item>
+                </Col>)
+              })}
+            </Row>
+          </Form>
+        </TitleWrap>
+        <TitleWrap title="缺省配置" wrapperStyle={{position: 'relative'}}>
+          <div className="topic-detail-options-wrapper">
+            <Button className="mr10" type="primary" size="small" onClick={() => onEdit()}>
+              编辑
+            </Button>
+          </div>
+          <Form form={form}>
+            <Row gutter={24}>
+              {['acceptPublish', 'acceptSubscribe', 'unflushThreshold', 'unflushInterval', 'deleteWhen', 'deletePolicy', 'numPartitions'].map((t: string, index: number) => {
+                if(!queryTopicConf.data || !queryTopicConf.data[0].topicInfo[0]) return null;
+                const value = queryTopicConf.data[0].topicInfo[0][t];
+                return (<Col span={12} key={'queryTopicConf' + index}>
+                  <Form.Item
+                    labelCol={{span: 12}}
+                    label={t}
+                  >
+                    {value + ''}
+                  </Form.Item>
+                </Col>)
+              })}
+            </Row>
+          </Form>
+        </TitleWrap>
+        <TitleWrap title="部署Broker列表">
+          {renderBrokerList()}
+        </TitleWrap>
+        <TitleWrap title="消费组列表">
+          {renderConsumeGroupList()}
+        </TitleWrap>
+      </div>
+      <CommonModal modalParams={modalParams} data={[queryTopicConf.data && queryTopicConf.data[0]]} />
+      <BrokerModal modalParams={brokerModalParams} data={[queryBrokerInfo.data && queryBrokerInfo.data[0]]} />
+    </Spin>
+  );
+};
+
+export default Detail;
diff --git a/web/src/pages/Topic/index.less b/web/src/pages/Topic/index.less
index c0e07eb..5efa767 100644
--- a/web/src/pages/Topic/index.less
+++ b/web/src/pages/Topic/index.less
@@ -1,6 +1,6 @@
-.broker-detail-options-wrapper {
+.topic-detail-options-wrapper {
   position: absolute;
-  top: 0;
+  top: 15px;
   right: 0;
 
   .mr10 {
diff --git a/web/src/pages/Topic/index.tsx b/web/src/pages/Topic/index.tsx
index d5b43c8..d85dc8b 100644
--- a/web/src/pages/Topic/index.tsx
+++ b/web/src/pages/Topic/index.tsx
@@ -148,7 +148,6 @@ const Topic: React.FC = () => {
         value: e,
         topicName: r.topicName,
         callback: () => {
-          debugger
           const index = data.findIndex(
             (t: TopicResultData) => t.topicName === r.topicName
           );
diff --git a/web/src/pages/Topic/query.tsx b/web/src/pages/Topic/query.tsx
index 13a4570..fc2a612 100644
--- a/web/src/pages/Topic/query.tsx
+++ b/web/src/pages/Topic/query.tsx
@@ -12,6 +12,7 @@ interface ComProps {
 }
 
 let newObjectTemp: string = '';
+let editObjectTemp: string = '';
 const Comp = (props: ComProps) => {
   const {fire} = props;
   const { userInfo } = useContext(GlobalContext);
@@ -33,6 +34,9 @@ const Comp = (props: ComProps) => {
       case 'editTopic':
         promise = editTopic(p);
         break;
+      case 'endEditChooseBroker':
+        promise = endEditChooseBroker(p);
+        break;
       case 'topicStateChange':
         promise = topicStateChange(type, p);
         break;
@@ -42,6 +46,9 @@ const Comp = (props: ComProps) => {
       case 'deleteTopic':
         promise = deleteTopic(type, p);
         break;
+      case 'deleteConsumeGroup':
+        promise = deleteConsumeGroup(type, p);
+        break;
     }
 
     promise && promise.then(t => {
@@ -49,7 +56,10 @@ const Comp = (props: ComProps) => {
       if(t.statusCode !== 0 && callback) callback(t);
     })
   };
-
+  const commonQuery = useRequest<any, any>(
+    (url, data) => ({ url, ...data }),
+    { manual: true }
+  );
   const newTopicQuery = useRequest<any, any>(
     data => ({ url: '/api/op_query/admin_query_broker_topic_config_info', ...data }),
     { manual: true }
@@ -80,28 +90,31 @@ const Comp = (props: ComProps) => {
     });
   };
 
-  const updateTopicQuery = useRequest<any, any>(
-    data => ({ url: '/api/op_modify/admin_update_broker_configure', ...data }),
-    { manual: true }
-  );
   const editTopic = (p: OKProps) => {
     const {params} = p;
-    return updateTopicQuery.run({
+    editObjectTemp = JSON.stringify(p.params);
+    return newTopicQuery.run({
+      data: {
+        topicName: params.topicName,
+        brokerId: '',
+      },
+    });
+  };
+  const endEditChooseBroker = (p: OKProps) => {
+    const topicParams = JSON.parse(editObjectTemp);
+    const {params} = p;
+    return commonQuery.run(`/api/op_modify/admin_modify_topic_info`, {
       data: {
-        ...params,
+        borkerId: params.selectBroker.join(','),
         confModAuthToken: p.psw,
-        createUser: userInfo.userName,
+        ...topicParams
       },
-    });
+    })
   };
 
-  const deleteTopicQuery = useRequest<any, any>(
-    (url, data) => ({ url, ...data }),
-    { manual: true }
-  );
   const deleteTopic = (type: string, p: OKProps) => {
     const { params } = p;
-    return deleteTopicQuery.run(`/api/op_modify/admin_delete_topic_info`, {
+    return commonQuery.run(`/api/op_modify/admin_delete_topic_info`, {
       data: {
         brokerId: params.selectBroker.join(','),
         confModAuthToken: p.psw,
@@ -110,11 +123,16 @@ const Comp = (props: ComProps) => {
       },
     });
   };
-
-  const topicStateChangeQuery = useRequest<any, any>(
-    (url, data) => ({ url, ...data }),
-    { manual: true }
-  );
+  const deleteConsumeGroup = (type: string, p: OKProps) => {
+    const { params } = p;
+    return commonQuery.run(`/api/op_modify/admin_delete_allowed_consumer_group_info`, {
+      data: {
+        groupName: params.groupName,
+        confModAuthToken: p.psw,
+        topicName: params.topicName
+      },
+    });
+  };
   const topicStateChange = (type: string, p: OKProps) => {
     const { params } = p;
     let data: {
@@ -134,15 +152,11 @@ const Comp = (props: ComProps) => {
       data.acceptSubscribe = params.value;
     }
 
-    return topicStateChangeQuery.run(`/api/op_modify/admin_modify_topic_info`, {
+    return commonQuery.run(`/api/op_modify/admin_modify_topic_info`, {
       data,
     });
   };
 
-  const authorizeControlQuery = useRequest<any, any>(
-    (url, data) => ({ url, ...data }),
-    { manual: true }
-  );
   const authorizeControl = (type: string, p: OKProps) => {
     const { params } = p;
     let data: {
@@ -156,7 +170,7 @@ const Comp = (props: ComProps) => {
       modifyUser: userInfo.userName,
     }
 
-    return authorizeControlQuery.run(`/api/op_modify/admin_set_topic_authorize_control`, {
+    return commonQuery.run(`/api/op_modify/admin_set_topic_authorize_control`, {
       data,
     });
   };
diff --git a/web/src/routes/index.tsx b/web/src/routes/index.tsx
index 7fce665..285711d 100644
--- a/web/src/routes/index.tsx
+++ b/web/src/routes/index.tsx
@@ -17,10 +17,10 @@ const routes: RouteProps[] = [
     path: '/broker',
     component: () => import('@/pages/Broker'),
   },
-  // {
-  //   path: '/topic/:id',
-  //   component: () => import('@/pages/Topic/detail'),
-  // },
+  {
+    path: '/topic/:name',
+    component: () => import('@/pages/Topic/detail'),
+  },
   {
     path: '/topic',
     component: () => import('@/pages/Topic'),
diff --git a/web/src/setupProxy.js b/web/src/setupProxy.js
index b2f9c72..533447c 100644
--- a/web/src/setupProxy.js
+++ b/web/src/setupProxy.js
@@ -4,9 +4,9 @@ const { createProxyMiddleware } = require('http-proxy-middleware');
 module.exports = function(app) {
   app.use(
     createProxyMiddleware('/webapi.htm', {
-      target: ' http://9.56.46.168:8080',
+      // target: ' http://9.56.46.168:8080',
       // target: 'http://10.224.148.145:8080',
-      // target: 'http://10.215.131.92:8080',
+      target: 'http://10.215.131.92:8080',
       changeOrigin: true,
       ws: true,
     })

[incubator-inlong] 07/10: feat(cluster): cluster manger done

Posted by do...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dockerzhang pushed a commit to branch new-web-client
in repository https://gitbox.apache.org/repos/asf/incubator-inlong.git

commit e54f14310d3003998213eb9de0beaee69d0f56b2
Author: zakwu <12...@qq.com>
AuthorDate: Tue Jun 30 15:13:31 2020 +0800

    feat(cluster): cluster manger done
---
 web/src/hooks/index.ts               |   9 ++-
 web/src/pages/Broker/commonModal.tsx |   5 +-
 web/src/pages/Cluster/index.less     |   0
 web/src/pages/Cluster/index.tsx      | 144 +++++++++++++++++++++++++++++++++++
 web/src/pages/Issue/index.tsx        |   4 +-
 web/src/routes/index.tsx             |   4 +
 6 files changed, 161 insertions(+), 5 deletions(-)

diff --git a/web/src/hooks/index.ts b/web/src/hooks/index.ts
index 6ce8168..ae1eecf 100644
--- a/web/src/hooks/index.ts
+++ b/web/src/hooks/index.ts
@@ -32,7 +32,14 @@ axios.interceptors.response.use(
       return Promise.reject(data);
     }
 
-    return data || [];
+    // set object outside data into it
+    const res = Object.assign({}, data)
+    delete res.errCode;
+    delete res.errMsg;
+    res.data = Object.assign(res.data, {
+      ...res
+    })
+    return res || [];
   },
   function(error) {
     return Promise.reject(error);
diff --git a/web/src/pages/Broker/commonModal.tsx b/web/src/pages/Broker/commonModal.tsx
index fb113d8..26480c4 100644
--- a/web/src/pages/Broker/commonModal.tsx
+++ b/web/src/pages/Broker/commonModal.tsx
@@ -224,11 +224,12 @@ export const onOpenModal = (p: BrokerModalProps) => {
           m.isOk = Date.now();
         })
       },
-      onCancel: () =>
+      onCancel: () => {
         updateFunction((m: any) => {
           m.visible = false;
           m.isOk = null;
-        }),
+        })
+      }
     });
   });
 };
diff --git a/web/src/pages/Cluster/index.less b/web/src/pages/Cluster/index.less
new file mode 100644
index 0000000..e69de29
diff --git a/web/src/pages/Cluster/index.tsx b/web/src/pages/Cluster/index.tsx
new file mode 100644
index 0000000..7164854
--- /dev/null
+++ b/web/src/pages/Cluster/index.tsx
@@ -0,0 +1,144 @@
+import React, { useContext } from 'react';
+import GlobalContext from '@/context/globalContext';
+import Breadcrumb from '@/components/Breadcrumb';
+import Table from '@/components/Tablex';
+import { Form, Input, Button, Spin } from 'antd';
+import './index.less';
+import { useRequest } from '@/hooks';
+import Modal, {OKProps} from "@/components/Modalx";
+import {useImmer} from "use-immer";
+
+interface ClusterResultData {
+  groupName: string;
+  groupStatus: string;
+  hostName: string;
+  index: number;
+  port: string;
+  nodeStatus: string;
+  length: number;
+}
+
+const queryClusterList = (data: ClusterResultData) => ({
+  url: '/api/op_query/admin_query_master_group_info',
+  data: data,
+});
+
+const Cluster: React.FC = () => {
+  const { breadMap } = useContext(GlobalContext);
+  const [modalParams, updateModelParams] = useImmer<any>({
+    title: '请确认操作',
+  });
+  const { data, loading, run } = useRequest<any, any>(queryClusterList, {
+    formatResult: d => {
+      return {
+        list: d.data.map((t: any) => ({
+          groupName: d.groupName,
+          groupStatus: d.groupStatus,
+          hostName: t.hostName,
+          index: t.index,
+          port: t.port,
+          nodeStatus: t.statusInfo.nodeStatus,
+          length: d.data.length
+        })),
+      };
+    }
+  });
+  const columns = [
+    {
+      title: '集群名',
+      dataIndex: 'groupName',
+      render: (t: string, r: ClusterResultData, index: number) => {
+        return {
+          children: t,
+          props: {
+            rowSpan: index === 0 ? r.length : 0
+          }
+        }
+      }
+    },
+    {
+      title: '集群状态',
+      dataIndex: 'groupStatus',
+      render: (t: string, r: ClusterResultData, index: number) => {
+        return {
+          children: t,
+          props: {
+            rowSpan: index === 0 ? r.length : 0
+          }
+        }
+      }
+    },
+    {
+      title: '节点名',
+      render: (t: string, r: ClusterResultData) => {
+        return `${r.groupName}-${r.hostName}`;
+      }
+    },
+    {
+      title: 'IP地址',
+      render: (t: string, r: ClusterResultData) => {
+        return `${r.hostName}-${r.port}`;
+      }
+    },
+    {
+      title: '节点名',
+      dataIndex: 'nodeStatus',
+    },
+    {
+      title: '操作',
+      render: (t: string, r: ClusterResultData, index: number) => {
+        return {
+          children: (<span className="options-wrapper">
+              <a onClick={() => onSwitchCluster(t, r)}>
+                切换
+              </a>
+          </span>),
+          props: {
+            rowSpan: index === 0 ? r.length : 0
+          }
+        }
+      }
+    },
+  ];
+
+  const switchClusterQuery = useRequest<any, any>((data?: ClusterResultData) => ({
+    url: '/api/op_modify/admin_transfer_current_master',
+    data,
+  }), { manual: true });
+  const onSwitchCluster = (t: string, r: ClusterResultData) => {
+      updateModelParams(d => {
+        d = Object.assign(d, {
+          visible: true,
+          onOk: (p: OKProps) => {
+            switchClusterQuery.run({
+              confModAuthToken: p.psw
+            })
+          },
+          onCancel: () => {
+            updateModelParams((m: any) => {
+              m.visible = false;
+            })
+          }
+        })
+      })
+  };
+  return (
+    <Spin spinning={loading}>
+      <Breadcrumb breadcrumbMap={breadMap}></Breadcrumb>
+      <div className="main-container">
+        <Table
+          columns={columns}
+          dataSource={data?.list}
+          rowKey="index"
+        ></Table>
+      </div>
+      <Modal {...modalParams} >
+        <div>
+          确认<span className="enhance">切换</span>集群?
+        </div>
+      </Modal>
+    </Spin>
+  );
+};
+
+export default Cluster;
diff --git a/web/src/pages/Issue/index.tsx b/web/src/pages/Issue/index.tsx
index bfedf64..54f5ad3 100644
--- a/web/src/pages/Issue/index.tsx
+++ b/web/src/pages/Issue/index.tsx
@@ -34,7 +34,7 @@ const columns = [
   },
 ];
 
-const queryUser = (data: IssueQueryData) => ({
+const queryIssueList = (data: IssueQueryData) => ({
   url: '/api/op_query/admin_query_sub_info',
   data: data,
 });
@@ -43,7 +43,7 @@ const Issue: React.FC = () => {
   const { breadMap } = useContext(GlobalContext);
   const [form] = Form.useForm();
   const [formValues, updateFormValues] = useImmer<any>({});
-  const { data, loading, run } = useRequest<any, IssueData>(queryUser, {});
+  const { data, loading, run } = useRequest<any, IssueData>(queryIssueList, {});
 
   const onValuesChange = (p: any) => {
     updateFormValues(d => {
diff --git a/web/src/routes/index.tsx b/web/src/routes/index.tsx
index 285711d..ee36fa2 100644
--- a/web/src/routes/index.tsx
+++ b/web/src/routes/index.tsx
@@ -26,6 +26,10 @@ const routes: RouteProps[] = [
     component: () => import('@/pages/Topic'),
   },
   {
+    path: '/cluster',
+    component: () => import('@/pages/Cluster'),
+  },
+  {
     component: () => import('@/pages/NotFound'),
   },
 ];

[incubator-inlong] 04/10: feat(broker):broker detail page complete

Posted by do...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dockerzhang pushed a commit to branch new-web-client
in repository https://gitbox.apache.org/repos/asf/incubator-inlong.git

commit 0e0143af7a21b169d74e931cd2f7e4c1d5f40325
Author: zakwu <12...@qq.com>
AuthorDate: Tue Jun 23 15:28:02 2020 +0800

    feat(broker):broker detail page complete
---
 web/src/components/Layout/index.tsx        |   2 +-
 web/src/components/Modalx/index.tsx        |   4 +-
 web/src/components/Tablex/index.tsx        |  10 +-
 web/src/components/TitleWrap/index.less    |   7 +
 web/src/components/TitleWrap/index.tsx     |  19 ++
 web/src/constants/broker.ts                |  18 ++
 web/src/pages/Broker/brokerDetail.tsx      | 305 ++++++++++++++++++++++++++
 web/src/pages/Broker/commonModal.tsx       | 261 ++++++++++++++++++++++
 web/src/pages/Broker/index.less            |   9 +
 web/src/pages/Broker/index.tsx             | 341 ++++++-----------------------
 web/src/pages/Broker/query.tsx             | 126 +++++++++++
 web/src/pages/Issue/consumeGroupDetail.tsx |  20 +-
 web/src/routes/index.tsx                   |   4 +
 web/src/utils/index.ts                     |  13 +-
 14 files changed, 830 insertions(+), 309 deletions(-)

diff --git a/web/src/components/Layout/index.tsx b/web/src/components/Layout/index.tsx
index 14c24f4..58ebb20 100644
--- a/web/src/components/Layout/index.tsx
+++ b/web/src/components/Layout/index.tsx
@@ -14,7 +14,7 @@ import './index.less';
 import GlobalContext from '@/context/globalContext';
 
 const BasicLayout: React.FC = props => {
-  const { cluster, setCluster, setBreadMap } = useContext(GlobalContext);
+  const { cluster, setBreadMap } = useContext(GlobalContext);
   const location = useLocation();
   const [settings, setSetting] = useState<SettingDrawerProps['settings']>(
     initSetting as SettingDrawerProps['settings']
diff --git a/web/src/components/Modalx/index.tsx b/web/src/components/Modalx/index.tsx
index 16a7831..6d42e82 100644
--- a/web/src/components/Modalx/index.tsx
+++ b/web/src/components/Modalx/index.tsx
@@ -1,10 +1,10 @@
 /**
  * TABLE COMPONENT WITH SEARCH
  */
-import { Modal, Input, Tooltip } from 'antd';
+import { Modal, Input } from 'antd';
 import * as React from 'react';
 import { ModalProps } from 'antd/lib/modal';
-import { ReactElement, useEffect } from 'react';
+import { ReactElement } from 'react';
 import './index.less';
 
 const { useState } = React;
diff --git a/web/src/components/Tablex/index.tsx b/web/src/components/Tablex/index.tsx
index 6e311ad..20d0cea 100644
--- a/web/src/components/Tablex/index.tsx
+++ b/web/src/components/Tablex/index.tsx
@@ -5,7 +5,7 @@ import { Table, Input, Row, Button, Col, Tooltip } from 'antd';
 import * as React from 'react';
 import { TableProps } from 'antd/lib/table';
 import { CaretDownFilled, CaretUpFilled } from '@ant-design/icons';
-import { isEmptyParam } from '../../utils';
+import { isEmptyParam } from '@/utils';
 import { useEffect } from 'react';
 import './index.less';
 
@@ -22,6 +22,7 @@ interface ComProps extends TableProps<any> {
   isTruePagination?: boolean;
   showSearch?: boolean;
   searchWidth?: number;
+  searchStyle?: any;
 }
 
 const Comp = (props: ComProps) => {
@@ -34,6 +35,7 @@ const Comp = (props: ComProps) => {
     isTruePagination,
     showSearch = true,
     searchWidth = 8,
+    searchStyle = {}
   } = props;
   const [filterKey, setFilterKey] = useState(defaultSearchKey);
   // 自动增加排序
@@ -62,7 +64,7 @@ const Comp = (props: ComProps) => {
 
     setFilterKey(defaultSearchKey || '');
     filterFnX && filterFnX(defaultSearchKey || '');
-  }, [defaultSearchKey]);
+  }, [defaultSearchKey, filterFnX]);
   // 分页如果只有一页,自动隐藏
   opts.pagination = Object.assign(
     {
@@ -84,8 +86,8 @@ const Comp = (props: ComProps) => {
   return (
     <>
       {showSearch && filterFnX && (
-        <Row gutter={20} className="mb10">
-          <Col span={searchWidth} style={{ padding: 0 }}>
+        <Row gutter={20} className="mb10" style={{position: 'relative'}}>
+          <Col span={searchWidth} style={{ padding: 0, ...searchStyle }}>
             <Tooltip title={filterKey}>
               <Search
                 value={filterKey}
diff --git a/web/src/components/TitleWrap/index.less b/web/src/components/TitleWrap/index.less
new file mode 100644
index 0000000..c44787f
--- /dev/null
+++ b/web/src/components/TitleWrap/index.less
@@ -0,0 +1,7 @@
+.title-wrap-title {
+  font-size: 16px;
+  font-weight: bold;
+  margin-top: 15px;
+  margin-bottom: 15px;
+  position: relative;
+}
diff --git a/web/src/components/TitleWrap/index.tsx b/web/src/components/TitleWrap/index.tsx
new file mode 100644
index 0000000..bcf125f
--- /dev/null
+++ b/web/src/components/TitleWrap/index.tsx
@@ -0,0 +1,19 @@
+import * as React from 'react';
+import './index.less';
+
+interface ComProps {
+  title: any;
+  children?: any;
+  wrapperStyle?: any;
+}
+
+const Comp = (props: ComProps) => {
+  return (
+    <div style={props.wrapperStyle}>
+      <div className="title-wrap-title">{props.title}</div>
+      {props.children}
+    </div>
+  );
+};
+
+export default Comp;
diff --git a/web/src/constants/broker.ts b/web/src/constants/broker.ts
new file mode 100644
index 0000000..e2b17c6
--- /dev/null
+++ b/web/src/constants/broker.ts
@@ -0,0 +1,18 @@
+export const BROKER_INFO_ZH_MAP = {
+  acceptPublish: '可发布',
+  acceptSubscribe: '可订阅',
+  brokerId: 'BrokerId',
+  brokerIp: 'BrokerIP',
+  brokerPort: 'BrokerPort',
+  brokerTLSPort: 'TLS端口',
+  brokerVersion: "版本",
+  enableTLS: '启用TLS',
+  isAutoForbidden: '自动屏蔽',
+  isBrokerOnline: 'broker注册',
+  isConfChanged: '配置变更',
+  isConfLoaded: '变更加载',
+  isRepAbnormal: '上报异常',
+  manageStatus: '管理状态',
+  runStatus: '运行状态',
+  subStatus: '运行子状态',
+};
\ No newline at end of file
diff --git a/web/src/pages/Broker/brokerDetail.tsx b/web/src/pages/Broker/brokerDetail.tsx
new file mode 100644
index 0000000..76cb696
--- /dev/null
+++ b/web/src/pages/Broker/brokerDetail.tsx
@@ -0,0 +1,305 @@
+import React, {ReactNode, useContext, useState} from 'react';
+import GlobalContext from '@/context/globalContext';
+import Breadcrumb from '@/components/Breadcrumb';
+import Table from '@/components/Tablex';
+import TitleWrap from '@/components/TitleWrap';
+import {Form, Button, Spin, Col, Row, Switch, Tabs} from 'antd';
+import { useImmer } from 'use-immer';
+import './index.less';
+import { useRequest } from '@/hooks';
+import {useParams} from 'react-router-dom';
+import {boolean2Chinese, transParamsWithConstantsMap} from "@/utils";
+import {BROKER_INFO_ZH_MAP} from "@/constants/broker";
+import tableFilterHelper from "@/components/Tablex/tableFilterHelper";
+import CommonModal, {OPTIONS, onOpenModal, BrokerData} from './commonModal'
+
+declare type BrokerQueryData = {
+  withDetail: boolean;
+  brokerId: string;
+};
+
+declare type TopicQueryData = {
+  withTopic: boolean;
+  brokerId: string;
+};
+
+const {TabPane} = Tabs;
+
+const BrokerDetail: React.FC = () => {
+  const { id } = useParams();
+  const { breadMap } = useContext(GlobalContext);
+  const [form] = Form.useForm();
+  const [modalParams, updateModelParams] = useImmer<any>({});
+  const [acceptPublish, setAcceptPublish] = useState<any>(false);
+  const [acceptSubscribe, setAcceptSubscribe] = useState<any>(false);
+  const [filterData, updateFilterData] = useImmer<any>({});
+  const queryBrokerConf = useRequest<any>((data: BrokerQueryData = {
+    withDetail: true,
+    brokerId: id,
+  }) => ({
+    url: '/api/op_query/admin_query_broker_run_status',
+    data: {
+      ...data
+    }
+  }), {
+    onSuccess: data => {
+      setAcceptPublish(data[0]['acceptPublish'] === 'true');
+      setAcceptSubscribe(data[0]['acceptSubscribe'] === 'true');
+    }
+  });
+  const queryTopicInfo = useRequest<any>((data: TopicQueryData = {
+    withTopic: true,
+    brokerId: id,
+  }) => ({
+    url: '/api/op_query/admin_query_broker_configure',
+    data: {
+      ...data
+    }
+  }));
+
+  // render
+  const renderConf = () => {
+    const columns = [{
+      title: '类别',
+      dataIndex: `type`,
+    },
+    {
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'acceptPublish'),
+      dataIndex: 'acceptPublish',
+      render: (t: string) => boolean2Chinese(t),
+    },
+    {
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'acceptSubscribe'),
+      dataIndex: 'acceptSubscribe',
+      render: (t: string) => boolean2Chinese(t),
+    },
+    {
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'unflushThreshold'),
+      dataIndex: 'unflushThreshold',
+    },
+    {
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'unflushInterval'),
+      dataIndex: 'unflushInterval',
+    },
+    {
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'deleteWhen'),
+      dataIndex: 'deleteWhen',
+    },
+    {
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'deletePolicy'),
+      dataIndex: 'deletePolicy',
+    },
+    {
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'numPartitions'),
+      dataIndex: 'numPartitions',
+    },
+    {
+      title: '操作',
+      render: (t:string, r: BrokerData) => {
+        return (<a onClick={() => onEditConf(r)}>编辑</a>)
+      }
+    }];
+    const {data} = queryBrokerConf;
+    if(!data || !data[0]) return null;
+    const {BrokerSyncStatusInfo} = data[0];
+    const dataSource = [];
+    dataSource.push({
+      type: '缺省配置',
+      ...BrokerSyncStatusInfo.curBrokerDefaultConfInfo
+    });
+    dataSource.push({
+      type: '最近上报',
+      ...BrokerSyncStatusInfo.reportedBrokerDefaultConfInfo
+    });
+    dataSource.push({
+      type: '最近下发',
+      ...BrokerSyncStatusInfo.lastPushBrokerDefaultConfInfo
+    });
+
+    return <Table columns={columns} dataSource={dataSource} rowKey="type" />;
+  }
+  const renderTopics = (type: string): ReactNode => {
+    const columns = [{
+      title: 'topicName',
+      dataIndex: `topicName`,
+    },
+    {
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'numPartitions'),
+      dataIndex: 'numPartitions',
+    },
+    {
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'acceptPublish'),
+      dataIndex: 'acceptPublish',
+      render: (t: string) => boolean2Chinese(t),
+    },
+    {
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'acceptSubscribe'),
+      dataIndex: 'acceptSubscribe',
+      render: (t: string) => boolean2Chinese(t),
+    },
+    {
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'unflushThreshold'),
+      dataIndex: 'unflushThreshold',
+    },
+    {
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'unflushInterval'),
+      dataIndex: 'unflushInterval',
+    },
+    {
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'deleteWhen'),
+      dataIndex: 'deleteWhen',
+    },
+    {
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, 'deletePolicy'),
+      dataIndex: 'deletePolicy',
+    }];
+    const {data} = queryBrokerConf;
+    if(!data || !data[0]) return null;
+    const {BrokerSyncStatusInfo} = data[0];
+    let dataSource: any[] = [];
+    if(type === 'cur') {
+      dataSource = BrokerSyncStatusInfo.curBrokerTopicSetConfInfo;
+    } else if(type === 'lastPush') {
+      dataSource = BrokerSyncStatusInfo.lastPushBrokerTopicSetConfInfo;
+    } else if(type === 'lastReported') {
+      dataSource = BrokerSyncStatusInfo.reportedBrokerTopicSetConfInfo;
+    }
+
+    return <Table columns={columns}
+                  dataSource={dataSource}
+                  rowKey={r => type + r.topicName}
+                  dataSourceX={filterData.list}
+                  searchPlaceholder="请输入TopicName搜索"
+                  searchStyle={{
+                    position: 'absolute',
+                    top: '-55px',
+                    right: '10px',
+                    zIndex: 1
+                  }}
+                  filterFnX={value =>
+                    tableFilterHelper({
+                      key: value,
+                      srcArray: dataSource,
+                      targetArray: filterData.list,
+                      updateFunction: res =>
+                        updateFilterData(filterData => {
+                          filterData.list = res;
+                        }),
+                      filterList: [
+                        'topicName',
+                      ],
+                    })
+                  }
+    />;
+  }
+
+  // event
+  // acceptPublish && acceptSubscribe event
+  const onSwitchChange = (e: boolean, type: string) => {
+    let option = '';
+    if (type === 'acceptPublish') {
+      option = e ? '发布' : '禁止发布';
+    } else if (type === 'acceptSubscribe') {
+      option = e ? '订阅' : '禁止订阅';
+    }
+
+    onOpenModal({
+      type: 'brokerStateChange',
+      title: `请确认操作`,
+      updateFunction: updateModelParams,
+      params: { option, id: queryBrokerConf.data[0].brokerId,
+        callback: () => {
+          if (type === 'acceptPublish') {
+            setAcceptPublish(e);
+          } else if (type === 'acceptSubscribe') {
+            setAcceptSubscribe(e);
+          }
+        }
+      }
+    });
+  };
+
+  const onOptions = (type: string) => {
+    onOpenModal({
+      type,
+      title: `确认进行【${OPTIONS.find(t => t.value === type)?.name}】操作?`,
+      updateFunction: updateModelParams,
+      params: [queryBrokerConf.data[0].brokerId],
+    });
+  }
+
+  // new broker
+  const onEditConf = (r: BrokerData) => {
+    onOpenModal({type: 'editBroker', title: '编辑Broker', updateFunction: updateModelParams, params: r})
+  }
+
+  return (
+    <Spin spinning={queryBrokerConf.loading && queryTopicInfo.loading}>
+      <Breadcrumb
+        breadcrumbMap={breadMap}
+        appendParams={`Broker(${id})`}
+      />
+      <div className="main-container">
+        <TitleWrap title="运行状态" wrapperStyle={{position: 'relative'}}>
+          <div className="broker-detail-options-wrapper">
+            <Switch
+              className="mr10"
+              checked={acceptPublish} checkedChildren="订阅" unCheckedChildren="订阅"
+              onChange={e => onSwitchChange(e, 'acceptPublish')}
+            />
+            <Switch
+              className="mr10"
+              checked={acceptSubscribe} checkedChildren="发布" unCheckedChildren="发布"
+              onChange={e => onSwitchChange(e, 'acceptSubscribe')}
+            />
+            <Button className="mr10" type="primary" size="small" onClick={() => onOptions('online')}>
+              上线
+            </Button>
+            <Button className="mr10" type="primary" size="small" onClick={() => onOptions('offline')}>
+              下线
+            </Button>
+            <Button className="mr10" type="primary" size="small"  onClick={() => onOptions('reload')}>
+              重载
+            </Button>
+          </div>
+          <Form form={form}>
+            <Row gutter={24}>
+              {queryBrokerConf.data && Object.keys(queryBrokerConf.data[0]).map((t: string, index: number) => {
+                const label = transParamsWithConstantsMap(BROKER_INFO_ZH_MAP, t);
+                const ignoreList = ['acceptPublish', 'brokerVersion', 'acceptSubscribe'];
+                if (queryBrokerConf.data[0][t] instanceof Object || !label || ignoreList.includes(t)) return null
+                return (<Col span={12} key={'queryBrokerConf' + index}>
+                  <Form.Item
+                    labelCol={{span: 12}}
+                    label={label}
+                  >
+                    {queryBrokerConf.data[0][t] + ''}
+                  </Form.Item>
+                </Col>)
+              })}
+            </Row>
+          </Form>
+        </TitleWrap>
+        <TitleWrap title="缺省配置">
+          {renderConf()}
+        </TitleWrap>
+        <TitleWrap title="Topic集合配置">
+          <Tabs>
+            <TabPane tab="当前配置" key="cur">
+              {renderTopics('cur')}
+            </TabPane>
+            <TabPane tab="最后下发" key="lastPush">
+              {renderTopics('lastPush')}
+            </TabPane>
+            <TabPane tab="最后上报" key="lastReported">
+              {renderTopics('lastReported')}
+            </TabPane>
+          </Tabs>
+        </TitleWrap>
+      </div>
+      <CommonModal modalParams={modalParams} data={[queryBrokerConf.data && queryBrokerConf.data[0]]} />
+    </Spin>
+  );
+};
+
+export default BrokerDetail;
diff --git a/web/src/pages/Broker/commonModal.tsx b/web/src/pages/Broker/commonModal.tsx
new file mode 100644
index 0000000..3543ebf
--- /dev/null
+++ b/web/src/pages/Broker/commonModal.tsx
@@ -0,0 +1,261 @@
+import {boolean2Chinese} from "@/utils";
+import Table from "@/components/Tablex";
+import {Col, Form, Input, Row} from "antd";
+import Modal, {OKProps} from "@/components/Modalx";
+import React from "react";
+import Query from "@/pages/Broker/query";
+import {FormProps} from "antd/lib/form";
+
+export const OPTIONS = [
+  {
+    value: 'online',
+    name: '上线',
+  },
+  {
+    value: 'offline',
+    name: '下线',
+  },
+  {
+    value: 'reload',
+    name: '重载',
+  },
+  {
+    value: 'delete',
+    name: '删除',
+  },
+];
+export const OPTIONS_VALUES = OPTIONS.map(t => t.value);
+
+
+// interface
+export declare type BrokerData = any[];
+export interface BrokerResultData {
+  acceptPublish: string;
+  acceptSubscribe: string;
+  brokerId: number;
+  brokerIp: string;
+  brokerPort: number;
+  brokerTLSPort: number;
+  brokerVersion: string;
+  enableTLS: boolean;
+  isAutoForbidden: boolean;
+  isBrokerOnline: string;
+  isConfChanged: string;
+  isConfLoaded: string;
+  isRepAbnormal: boolean;
+  manageStatus: string;
+  runStatus: string;
+  subStatus: string;
+  [key: string]: any;
+}
+export interface BrokerModalProps {
+  type: string;
+  title: string;
+  updateFunction: (draft: any) => any;
+  params?: any;
+}
+// exports broker modal
+// render funcs
+const renderBrokerOptions = (modalParams: any, dataSource: any[]) => {
+  const columns = [
+    {
+      title: 'Broker',
+      render: (t: string, r: BrokerResultData) => {
+        return `${r.brokerId}#${r.brokerIp}:${r.brokerPort}`;
+      },
+    },
+    {
+      title: 'BrokerIP',
+      dataIndex: 'brokerIp',
+    },
+    {
+      title: '管理状态',
+      dataIndex: 'manageStatus',
+    },
+    {
+      title: '运行状态',
+      dataIndex: 'runStatus',
+    },
+    {
+      title: '运行子状态',
+      dataIndex: 'subStatus',
+    },
+    {
+      title: '可发布',
+      render: (t: string) => boolean2Chinese(t),
+    },
+    {
+      title: '可订阅',
+      render: (t: string) => boolean2Chinese(t),
+    },
+  ];
+  return (
+    <Table
+      columns={columns}
+      dataSource={dataSource}
+      rowKey="brokerId"
+    />
+  );
+};
+const renderNewBroker = (form: any) => {
+  const brokerFormArr = [
+    {
+      name: 'brokerId',
+      defaultValue: '0',
+    },
+    {
+      name: 'numPartitions',
+      defaultValue: '3',
+    },
+    {
+      name: 'brokerIp',
+      defaultValue: '',
+    },
+    {
+      name: 'brokerPort',
+      defaultValue: '8123',
+    },
+    {
+      name: 'deleteWhen',
+      defaultValue: '0 0 6,18 * * ?',
+    },
+    {
+      name: 'deletePolicy',
+      defaultValue: 'delete,168h',
+    },
+    {
+      name: 'unflushThreshold',
+      defaultValue: '1000',
+    },
+    {
+      name: 'unflushInterval',
+      defaultValue: '10000',
+    },
+    {
+      name: 'acceptPublish',
+      defaultValue: 'true',
+    },
+    {
+      name: 'acceptSubscribe',
+      defaultValue: 'true',
+    },
+  ];
+
+  return (
+    <Form form={form}>
+      <Row gutter={24}>
+        {brokerFormArr.map((t, index) => (
+          <Col span={12} key={'brokerFormArr' + index}>
+            <Form.Item
+              labelCol={{ span: 12 }}
+              label={t.name}
+              name={t.name}
+              initialValue={t.defaultValue}
+            >
+              <Input />
+            </Form.Item>
+          </Col>
+        ))}
+      </Row>
+    </Form>
+  );
+};
+const renderEditBroker = (modalParams: any, form: FormProps['form']) => {
+  const {params: p} = modalParams;
+  const pickArr = ['numPartitions', 'unflushThreshold', 'unflushInterval', 'deleteWhen', 'deletePolicy', 'acceptPublish', 'acceptSubscribe'];
+  let brokerFormArr : Array<{
+    name: string;
+    defaultValue: string;
+  }> = [];
+  pickArr.forEach(t => {
+    brokerFormArr.push({
+      name: t,
+      defaultValue: p[t]
+    })
+  })
+
+  return (
+    <Form form={form}>
+      <Row gutter={24}>
+        {brokerFormArr.map((t, index) => (
+          <Col span={12} key={'brokerFormArr' + index}>
+            <Form.Item
+              labelCol={{ span: 12 }}
+              label={t.name}
+              name={t.name}
+              initialValue={t.defaultValue}
+            >
+              <Input />
+            </Form.Item>
+          </Col>
+        ))}
+      </Row>
+    </Form>
+  );
+};
+const renderBrokerStateChange = (modalParams: any) => {
+  const { params } = modalParams;
+
+  return (
+    <div>
+      请确认<span className="enhance">{params.option}</span> ID:{' '}
+      <span className="enhance">{params.id}</span> 的 Broker?
+    </div>
+  );
+};
+export const onOpenModal = (p: BrokerModalProps) => {
+  const {type, title, updateFunction, params} = p;
+  if(typeof params === 'function') {
+    p.params = params();
+  }
+  updateFunction((m: any) => {
+    m.type = type;
+    m.params = params;
+    Object.assign(m, {
+      params,
+      visible: type,
+      title,
+      onOk: (p: OKProps) => {
+        updateFunction((m: any) => {
+          if(type === 'newBroker' || type === 'editBroker') {
+            p.params = f && f.getFieldsValue()
+          }
+          m.okParams = p;
+          m.isOk = Date.now();
+        })
+      },
+      onCancel: () =>
+        updateFunction((m: any) => {
+          m.visible = false;
+        }),
+    });
+  });
+};
+
+interface ComProps {
+  modalParams: any;
+  data: any[];
+}
+let f: FormProps['form'];
+const Comp = (props: ComProps) => {
+  const {modalParams, data} = props;
+  const [form] = Form.useForm();
+  f = form;
+
+  return (
+    <Modal {...modalParams}>
+      <div>
+        {modalParams.type &&
+        OPTIONS_VALUES.includes(modalParams.type) && renderBrokerOptions(modalParams, data.filter((t: BrokerResultData) =>
+          modalParams.params.includes(t.brokerId)
+        ))}
+        {modalParams.type === 'newBroker' && renderNewBroker(form)}
+        {modalParams.type === 'editBroker' && renderEditBroker(modalParams, form)}
+        {modalParams.type === 'brokerStateChange' && renderBrokerStateChange(modalParams)}
+      </div>
+      <Query fire={modalParams.isOk} params={modalParams.okParams} type={modalParams.type} />
+    </Modal>
+  )
+};
+
+export default Comp;
\ No newline at end of file
diff --git a/web/src/pages/Broker/index.less b/web/src/pages/Broker/index.less
index e69de29..c0e07eb 100644
--- a/web/src/pages/Broker/index.less
+++ b/web/src/pages/Broker/index.less
@@ -0,0 +1,9 @@
+.broker-detail-options-wrapper {
+  position: absolute;
+  top: 0;
+  right: 0;
+
+  .mr10 {
+    margin-right: 10px;
+  }
+}
\ No newline at end of file
diff --git a/web/src/pages/Broker/index.tsx b/web/src/pages/Broker/index.tsx
index 644f3e2..2322384 100644
--- a/web/src/pages/Broker/index.tsx
+++ b/web/src/pages/Broker/index.tsx
@@ -2,100 +2,48 @@ import React, { useContext, useState } from 'react';
 import GlobalContext from '@/context/globalContext';
 import Breadcrumb from '@/components/Breadcrumb';
 import Table from '@/components/Tablex';
-import Modal, { OKProps } from '@/components/Modalx';
-import {
-  Form,
-  Select,
-  Button,
-  Spin,
-  Switch,
-  Input,
-  Row,
-  Col,
-  message,
-} from 'antd';
+import { Form, Select, Button, Spin, Switch, message} from 'antd';
 import { useImmer } from 'use-immer';
 import { useRequest } from '@/hooks';
 import tableFilterHelper from '@/components/Tablex/tableFilterHelper';
-import { boolean2Chinese } from '@/utils';
+import { boolean2Chinese, transParamsWithConstantsMap } from '@/utils';
+import {BROKER_INFO_ZH_MAP} from '@/constants/broker';
 import './index.less';
+import {Link} from "react-router-dom";
+import CommonModal, {OPTIONS, onOpenModal, BrokerResultData, BrokerData} from './commonModal'
 
-declare type BrokerData = any[];
-interface BrokerResultData {
-  acceptPublish: string;
-  acceptSubscribe: string;
-  brokerId: number;
-  brokerIp: string;
-  brokerPort: number;
-  brokerTLSPort: number;
-  brokerVersion: string;
-  enableTLS: boolean;
-  isAutoForbidden: boolean;
-  isBrokerOnline: string;
-  isConfChanged: string;
-  isConfLoaded: string;
-  isRepAbnormal: boolean;
-  manageStatus: string;
-  runStatus: string;
-  subStatus: string;
-  [key: string]: any;
-}
-
-const { Option } = Select;
-const OPTIONS = [
-  {
-    value: 'online',
-    name: '上线',
-  },
-  {
-    value: 'offline',
-    name: '下线',
-  },
-  {
-    value: 'reload',
-    name: '重载',
-  },
-  {
-    value: 'delete',
-    name: '删除',
-  },
-];
-const OPTIONS_VALUES = OPTIONS.map(t => t.value);
-const queryBroker = (data: BrokerResultData) => ({
-  url: '/api/op_query/admin_query_broker_run_status',
-  data: data,
-});
-
+const {Option} = Select;
 const Broker: React.FC = () => {
   // column config
   const columns = [
     {
-      title: 'BrokerID',
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'brokerId'),
       dataIndex: 'brokerId',
       fixed: 'left',
+      render: (t: Array<any>) => <Link to={'/broker/' + t}>{t}</Link>,
     },
     {
-      title: 'BrokerIP',
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'brokerIp'),
       dataIndex: 'brokerIp',
     },
     {
-      title: 'BrokerPort',
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'brokerPort'),
       dataIndex: 'brokerPort',
     },
     {
-      title: '管理状态',
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'manageStatus'),
       dataIndex: 'manageStatus',
     },
     {
-      title: '运行状态',
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'runStatus'),
       dataIndex: 'runStatus',
     },
     {
-      title: '运行子状态',
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'subStatus'),
       dataIndex: 'subStatus',
     },
     {
-      title: '可发布',
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'acceptPublish'),
       dataIndex: 'acceptPublish',
       render: (t: string, r: BrokerResultData) => {
         return (
@@ -107,7 +55,7 @@ const Broker: React.FC = () => {
       },
     },
     {
-      title: '可订阅',
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'acceptSubscribe'),
       dataIndex: 'acceptSubscribe',
       render: (t: string, r: BrokerResultData) => {
         return (
@@ -119,42 +67,42 @@ const Broker: React.FC = () => {
       },
     },
     {
-      title: '配置变更',
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'isConfChanged'),
       dataIndex: 'isConfChanged',
       render: (t: string) => boolean2Chinese(t),
     },
     {
-      title: '变更加载',
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'isConfLoaded'),
       dataIndex: 'isConfLoaded',
       render: (t: string) => boolean2Chinese(t),
     },
     {
-      title: 'broker注册',
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'isBrokerOnline'),
       dataIndex: 'isBrokerOnline',
       render: (t: string) => boolean2Chinese(t),
     },
     {
-      title: '上线',
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'acceptPublish'),
       dataIndex: 'isBrokerOnline',
       render: (t: string) => boolean2Chinese(t),
     },
     {
-      title: 'TLS端口',
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'brokerTLSPort'),
       dataIndex: 'brokerTLSPort',
       render: (t: string) => boolean2Chinese(t),
     },
     {
-      title: '启用TLS',
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'enableTLS'),
       dataIndex: 'enableTLS',
       render: (t: boolean) => boolean2Chinese(t),
     },
     {
-      title: '上报异常',
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'isRepAbnormal'),
       dataIndex: 'isRepAbnormal',
       render: (t: boolean) => boolean2Chinese(t),
     },
     {
-      title: '自动屏蔽',
+      title: transParamsWithConstantsMap(BROKER_INFO_ZH_MAP,'isAutoForbidden'),
       dataIndex: 'isAutoForbidden',
       render: (t: boolean) => boolean2Chinese(t),
     },
@@ -167,7 +115,7 @@ const Broker: React.FC = () => {
         return (
           <span className="options-wrapper">
             {OPTIONS.map(t => (
-              <a key={t.value} onClick={() => onOptionsChange(t.value, r)}>
+              <a href="#" key={t.value} onClick={() => onOptionsChange(t.value, r)}>
                 {t.name}
               </a>
             ))}
@@ -176,165 +124,27 @@ const Broker: React.FC = () => {
       },
     },
   ];
-  const { breadMap, userInfo } = useContext(GlobalContext);
+  const { breadMap } = useContext(GlobalContext);
   const [modalParams, updateModelParams] = useImmer<any>({});
   const [filterData, updateFilterData] = useImmer<any>({});
   const [selectBroker, setSelectBroker] = useState<any>([]);
   const [brokerList, updateBrokerList] = useImmer<BrokerData>([]);
   const [form] = Form.useForm();
-  const [newBrokerForm] = Form.useForm();
   // init query
-  const { data, loading, run } = useRequest<any, BrokerData>(queryBroker, {
+  const { data, loading, run } = useRequest<any, BrokerData>((data: BrokerResultData) => ({
+    url: '/api/op_query/admin_query_broker_run_status',
+    data: data,
+  }), {
     onSuccess: data => {
       updateBrokerList(d => {
         Object.assign(d, data);
       });
     },
   });
-  // render funcs
-  const renderBrokerOptions = () => {
-    const columns = [
-      {
-        title: 'Broker',
-        render: (t: string, r: BrokerResultData) => {
-          return `${r.brokerId}#${r.brokerIp}:${r.brokerPort}`;
-        },
-      },
-      {
-        title: 'BrokerIP',
-        dataIndex: 'brokerIp',
-      },
-      {
-        title: '管理状态',
-        dataIndex: 'manageStatus',
-      },
-      {
-        title: '运行状态',
-        dataIndex: 'runStatus',
-      },
-      {
-        title: '运行子状态',
-        dataIndex: 'subStatus',
-      },
-      {
-        title: '可发布',
-        render: (t: string) => boolean2Chinese(t),
-      },
-      {
-        title: '可订阅',
-        render: (t: string) => boolean2Chinese(t),
-      },
-    ];
-    const dataSource = data.filter((t: BrokerResultData) =>
-      modalParams.params.includes(t.brokerId)
-    );
-    return (
-      <Table
-        columns={columns}
-        dataSource={dataSource}
-        rowKey="brokerId"
-      ></Table>
-    );
-  };
-  const renderNewBroker = () => {
-    const brokerFormArr = [
-      {
-        name: 'brokerId',
-        defaultValue: '0',
-      },
-      {
-        name: 'numPartitions',
-        defaultValue: '3',
-      },
-      {
-        name: 'brokerIP',
-        defaultValue: '',
-      },
-      {
-        name: 'brokerPort',
-        defaultValue: '8123',
-      },
-      {
-        name: 'deleteWhen',
-        defaultValue: '0 0 6,18 * * ?',
-      },
-      {
-        name: 'deletePolicy',
-        defaultValue: 'delete,168h',
-      },
-      {
-        name: 'unflushThreshold',
-        defaultValue: '1000',
-      },
-      {
-        name: 'unflushInterval',
-        defaultValue: '10000',
-      },
-      {
-        name: 'acceptPublish',
-        defaultValue: 'true',
-      },
-      {
-        name: 'acceptSubscribe',
-        defaultValue: 'true',
-      },
-    ];
-
-    return (
-      <Form form={newBrokerForm}>
-        <Row gutter={24}>
-          {brokerFormArr.map((t, index) => (
-            <Col span={12} key={'brokerFormArr' + index}>
-              <Form.Item
-                labelCol={{ span: 12 }}
-                label={t.name}
-                name={t.name}
-                initialValue={t.defaultValue}
-              >
-                <Input />
-              </Form.Item>
-            </Col>
-          ))}
-        </Row>
-      </Form>
-    );
-  };
-  const renderBrokerStateChange = () => {
-    const { params } = modalParams;
 
-    return (
-      <div>
-        请确认<span className="enhance">{params.option}</span> ID:{' '}
-        <span className="enhance">{params.id}</span> 的 Broker?
-      </div>
-    );
-  };
-
-  // events
-  const onOpenModal = (type: string, title: string, params?: any) => {
-    updateModelParams(m => {
-      m.type = type;
-      m.params = params;
-      Object.assign(m, {
-        params,
-        visible: type,
-        title,
-        onOk: (p: OKProps) => onModelOk(type, p),
-        onCancel: () =>
-          updateModelParams(m => {
-            m.visible = false;
-          }),
-      });
-    });
-  };
   // table event
+  // acceptSubscribe && acceptPublish options
   const onSwitchChange = (e: boolean, r: BrokerResultData, type: string) => {
-    const index = data.findIndex(
-      (t: BrokerResultData) => t.brokerId === r.brokerId
-    );
-    updateBrokerList(d => {
-      d[index][type] = e + '';
-    });
     let option = '';
     if (type === 'acceptPublish') {
       option = e ? '发布' : '禁止发布';
@@ -342,66 +152,50 @@ const Broker: React.FC = () => {
       option = e ? '订阅' : '禁止订阅';
     }
 
-    onOpenModal('brokerStateChange', `请确认操作`, { option, id: r.brokerId });
+    onOpenModal({
+      type: 'brokerStateChange',
+      title: `请确认操作`,
+      updateFunction: updateModelParams,
+      params: {
+        option,
+        id: r.brokerId,
+        type,
+        callback: () => {
+          const index = data.findIndex(
+            (t: BrokerResultData) => t.brokerId === r.brokerId
+          );
+          updateBrokerList(d => {
+            d[index][type] = e + '';
+          });
+        }},
+    });
   };
-  const onBrokerTableSelectChange = (p: any[], rows: any[]) => {
-    setSelectBroker(p);
+  // new broker
+  const onNewBroker = () => {
+    onOpenModal({type: 'newBroker', title: '新建Broker', updateFunction: updateModelParams})
   };
-
-  // modal event
+  // online, offline, etc.
   const onOptionsChange = (type: string, r?: BrokerResultData) => {
     if (!r && !selectBroker.length) {
       form.resetFields();
       return message.error('批量操作至少选择一列!');
     }
-    onOpenModal(
-      type,
-      `确认进行【${OPTIONS.find(t => t.value === type)?.name}】操作?`,
-      [r?.brokerId]
-    );
-  };
-  const onModelOk = (type: string, p: OKProps) => {
-    switch (type) {
-      case 'newBroker':
-        return newBroker(p);
-      default:
-        return brokerOptions(type, p);
-    }
-  };
 
-  const newBrokerQuery = useRequest<any, any>(
-    data => ({ url: '/api/op_modify/admin_add_broker_configure', ...data }),
-    { manual: true }
-  );
-  const newBroker = (p: OKProps) => {
-    const values = newBrokerForm.getFieldsValue();
-    newBrokerQuery.run({
-      data: {
-        ...values,
-        confModAuthToken: p.psw,
-        createUser: userInfo.userName,
-      },
+    onOpenModal({
+      type,
+      title: `确认进行【${OPTIONS.find(t => t.value === type)?.name}】操作?`,
+      updateFunction: updateModelParams,
+      params: r ? [r.brokerId] : selectBroker,
     });
   };
-
-  const brokerOptionsQuery = useRequest<any, any>(
-    (url, data) => ({ url, ...data }),
-    { manual: true }
-  );
-  const brokerOptions = (type: string, p: OKProps) => {
-    const { params } = p;
-    brokerOptionsQuery.run(`/api/op_modify/admin_${type}_broker_configure`, {
-      data: {
-        brokerId: params ? params?.join(',') : selectBroker.join(','),
-        confModAuthToken: p.psw,
-        createUser: userInfo.userName,
-      },
-    });
+  // table select
+  const onBrokerTableSelectChange = (p: any[]) => {
+    setSelectBroker(p);
   };
 
   return (
     <Spin spinning={loading}>
-      <Breadcrumb breadcrumbMap={breadMap}></Breadcrumb>
+      <Breadcrumb breadcrumbMap={breadMap} />
       <div className="main-container">
         <div
           className="search-wrapper"
@@ -424,7 +218,7 @@ const Broker: React.FC = () => {
             <Form.Item>
               <Button
                 type="primary"
-                onClick={() => onOpenModal('newBroker', '新建Broker')}
+                onClick={() => onNewBroker()}
                 style={{ margin: '0 10px 0 10px' }}
               >
                 新增
@@ -463,18 +257,9 @@ const Broker: React.FC = () => {
               ],
             })
           }
-        ></Table>
+        />
       </div>
-      <Modal {...modalParams}>
-        <div>
-          {modalParams.type &&
-            OPTIONS_VALUES.includes(modalParams.type) &&
-            renderBrokerOptions()}
-          {modalParams.type === 'newBroker' && renderNewBroker()}
-          {modalParams.type === 'brokerStateChange' &&
-            renderBrokerStateChange()}
-        </div>
-      </Modal>
+      <CommonModal modalParams={modalParams} data={data} />
     </Spin>
   );
 };
diff --git a/web/src/pages/Broker/query.tsx b/web/src/pages/Broker/query.tsx
new file mode 100644
index 0000000..6f8b8e9
--- /dev/null
+++ b/web/src/pages/Broker/query.tsx
@@ -0,0 +1,126 @@
+import * as React from 'react';
+import './index.less';
+import {OKProps} from "@/components/Modalx";
+import {useRequest} from "@/hooks";
+import {useContext, useEffect} from "react";
+import GlobalContext from "@/context/globalContext";
+
+interface ComProps {
+  fire: string;
+  params: any;
+  type: string;
+}
+
+const Comp = (props: ComProps) => {
+  const {fire} = props;
+  const { userInfo } = useContext(GlobalContext);
+  useEffect(() => {
+    const {params, type} = props;
+    dispatchAction(type, params);
+  }, [fire, props]);
+
+  const dispatchAction = (type: string, p: OKProps) => {
+    if(!fire) return null;
+    let promise;
+    switch (type) {
+      case 'newBroker':
+        promise = newBroker(p);
+        break;
+      case 'editBroker':
+        promise = editBroker(p);
+        break;
+      case 'brokerStateChange':
+        promise = brokerAcceptPublish(type, p);
+        break;
+      case 'online':
+      case 'offline':
+      case 'reload':
+      case 'delete':
+        promise = brokerOptions(type, p);
+        break;
+    }
+
+    promise && promise.then(t => {
+      const {callback} = p.params;
+      if(t.statusCode !== 0 && callback) callback(t);
+    })
+  };
+
+  const newBrokerQuery = useRequest<any, any>(
+    data => ({ url: '/api/op_modify/admin_add_broker_configure', ...data }),
+    { manual: true }
+  );
+  const newBroker = (p: OKProps) => {
+    const {params} = p;
+    return newBrokerQuery.run({
+      data: {
+        ...params,
+        confModAuthToken: p.psw,
+        createUser: userInfo.userName,
+      },
+    });
+  };
+
+  const updateBrokerQuery = useRequest<any, any>(
+    data => ({ url: '/api/op_modify/admin_update_broker_configure', ...data }),
+    { manual: true }
+  );
+  const editBroker = (p: OKProps) => {
+    const {params} = p;
+    return updateBrokerQuery.run({
+      data: {
+        ...params,
+        confModAuthToken: p.psw,
+        createUser: userInfo.userName,
+      },
+    });
+  };
+
+  const brokerOptionsQuery = useRequest<any, any>(
+    (url, data) => ({ url, ...data }),
+    { manual: true }
+  );
+  const brokerOptions = (type: string, p: OKProps) => {
+    const { params } = p;
+    return brokerOptionsQuery.run(`/api/op_modify/admin_${type}_broker_configure`, {
+      data: {
+        brokerId: params ? params?.join(',') : params?.selectBroker.join(','),
+        confModAuthToken: p.psw,
+        createUser: userInfo.userName,
+      },
+    });
+  };
+
+  const brokerAcceptPublishQuery = useRequest<any, any>(
+    (url, data) => ({ url, ...data }),
+    { manual: true }
+  );
+  const brokerAcceptPublish = (type: string, p: OKProps) => {
+    const { params } = p;
+    let data: {
+      [key: string]: any;
+    };
+
+    data = {
+      brokerId: params.id,
+      confModAuthToken: p.psw,
+      createUser: userInfo.userName,
+    }
+    if(params.type === 'acceptPublish') {
+      data.isAcceptPublish = params.option;
+    }
+    if(params.type === 'acceptSubscribe') {
+      data.isAcceptSubscribe = params.option;
+    }
+
+    return brokerAcceptPublishQuery.run(`/api/op_modify/admin_set_broker_read_or_write`, {
+      data,
+    });
+  };
+
+  return (
+    <></>
+  );
+};
+
+export default Comp;
diff --git a/web/src/pages/Issue/consumeGroupDetail.tsx b/web/src/pages/Issue/consumeGroupDetail.tsx
index 8b2f562..3c5090f 100644
--- a/web/src/pages/Issue/consumeGroupDetail.tsx
+++ b/web/src/pages/Issue/consumeGroupDetail.tsx
@@ -3,7 +3,7 @@ import GlobalContext from '@/context/globalContext';
 import Breadcrumb from '@/components/Breadcrumb';
 import Table from '@/components/Tablex';
 import tableFilterHelper from '@/components/Tablex/tableFilterHelper';
-import { Form, Input, Button, Spin } from 'antd';
+import { Spin } from 'antd';
 import { useImmer } from 'use-immer';
 import './index.less';
 import { useRequest } from '@/hooks';
@@ -42,10 +42,8 @@ const queryUser = (data: ConsumeGroupQueryData) => ({
 const ConsumeGroupDetail: React.FC = () => {
   const { id } = useParams();
   const { breadMap } = useContext(GlobalContext);
-  const [form] = Form.useForm();
-  const [formValues, updateFormValues] = useImmer<any>({});
   const [filterData, updateFilterData] = useImmer<any>({});
-  const { data, loading, run } = useRequest<any, ConsumeGroupData>(
+  const { data, loading } = useRequest<any, ConsumeGroupData>(
     () =>
       queryUser({
         consumeGroup: id,
@@ -63,20 +61,6 @@ const ConsumeGroupDetail: React.FC = () => {
     }
   );
 
-  const onValuesChange = (p: any) => {
-    updateFormValues(d => {
-      Object.assign(d, p);
-    });
-  };
-  const onSearch = () => {
-    run(formValues);
-  };
-
-  const onReset = () => {
-    form.resetFields();
-    run({});
-  };
-
   return (
     <Spin spinning={loading}>
       <Breadcrumb
diff --git a/web/src/routes/index.tsx b/web/src/routes/index.tsx
index 7cbd3d6..c05340f 100644
--- a/web/src/routes/index.tsx
+++ b/web/src/routes/index.tsx
@@ -10,6 +10,10 @@ const routes: RouteProps[] = [
     component: () => import('@/pages/Issue'),
   },
   {
+    path: '/broker/:id',
+    component: () => import('@/pages/Broker/brokerDetail'),
+  },
+  {
     path: '/broker',
     component: () => import('@/pages/Broker'),
   },
diff --git a/web/src/utils/index.ts b/web/src/utils/index.ts
index aadcc68..d741565 100644
--- a/web/src/utils/index.ts
+++ b/web/src/utils/index.ts
@@ -1,10 +1,7 @@
 import { isObject, isEmpty } from 'lodash';
 
 export const isDevelopEnv = () => {
-  if (process.env.NODE_ENV === 'development') {
-    return true;
-  }
-  return false;
+  return process.env.NODE_ENV === 'development'
 };
 
 export const isEmptyParam = (value: any): boolean => {
@@ -29,7 +26,7 @@ export const isEmptyParam = (value: any): boolean => {
 };
 
 export const boolean2Chinese = (value: boolean | string): string => {
-  let v = false;
+  let v: boolean;
   if (value === 'false') {
     v = false;
   } else if (value === 'true') {
@@ -37,5 +34,9 @@ export const boolean2Chinese = (value: boolean | string): string => {
   } else {
     v = value as boolean;
   }
-  return v === false ? '否' : '是';
+  return !v ? '否' : '是';
 };
+
+export const transParamsWithConstantsMap = (map: any, paramsName: string): string => {
+  return map[paramsName] || paramsName;
+}

[incubator-inlong] 10/10: fix(request): request menu css issue

Posted by do...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dockerzhang pushed a commit to branch new-web-client
in repository https://gitbox.apache.org/repos/asf/incubator-inlong.git

commit a6d697dce2ef0b7fcc2927c1ecb264dc398f3fac
Author: zakwu <12...@qq.com>
AuthorDate: Fri Nov 6 14:13:53 2020 +0800

    fix(request): request menu css issue
---
 web/src/components/Layout/index.less | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/web/src/components/Layout/index.less b/web/src/components/Layout/index.less
index 4d0184e..6e0ed86 100644
--- a/web/src/components/Layout/index.less
+++ b/web/src/components/Layout/index.less
@@ -24,4 +24,8 @@
   a {
     margin-right: 8px;
   }
+}
+
+.ant-layout-sider-collapsed .ant-pro-sider-menu-logo {
+  margin-left: -15px;
 }
\ No newline at end of file

[incubator-inlong] 03/10: feat(broker): broker complete

Posted by do...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dockerzhang pushed a commit to branch new-web-client
in repository https://gitbox.apache.org/repos/asf/incubator-inlong.git

commit 47b69ec5c4a90fe9a0d2a4689a811fcb42235469
Author: zakwu <12...@qq.com>
AuthorDate: Fri Jun 19 15:44:50 2020 +0800

    feat(broker): broker complete
---
 web/src/components/Breadcrumb/index.tsx        |   2 +-
 web/src/components/Layout/index.less           |   8 +-
 web/src/components/Modalx/index.less           |  17 +
 web/src/components/Modalx/index.tsx            |  49 +++
 web/src/components/Tablex/index.tsx            |   4 +-
 web/src/components/Tablex/tableFilterHelper.ts |  32 ++
 web/src/configs/menus/index.tsx                |   5 +-
 web/src/context/globalContext.ts               |   1 +
 web/src/pages/Broker/index.less                |   0
 web/src/pages/Broker/index.tsx                 | 482 +++++++++++++++++++++++++
 web/src/pages/Issue/consumeGroupDetail.tsx     |  16 +
 web/src/router.tsx                             |   5 +-
 web/src/routes/index.tsx                       |   4 +-
 web/src/utils/index.ts                         |  12 +
 14 files changed, 629 insertions(+), 8 deletions(-)

diff --git a/web/src/components/Breadcrumb/index.tsx b/web/src/components/Breadcrumb/index.tsx
index 4d41369..c4113bf 100644
--- a/web/src/components/Breadcrumb/index.tsx
+++ b/web/src/components/Breadcrumb/index.tsx
@@ -19,7 +19,7 @@ const BasicLayout: React.FC<BreadcrumbProps> = props => {
     const breadcrumbNameMap = {} as any;
     breadcrumbMap &&
       breadcrumbMap.forEach((t: MenuDataItem) => {
-        breadcrumbNameMap[t.pro_layout_parentKeys.join('/') + t.key] = t.name;
+        breadcrumbNameMap[t.key as string] = t.name;
       });
     const url = `/${pathSnippets.slice(0, index + 1).join('/')}`;
     if (appendParams && index === pathSnippets.length - 1) {
diff --git a/web/src/components/Layout/index.less b/web/src/components/Layout/index.less
index 9811a7d..4d0184e 100644
--- a/web/src/components/Layout/index.less
+++ b/web/src/components/Layout/index.less
@@ -13,9 +13,15 @@
 // global css
 .main-container {
   background: #fff;
-  padding: 20px;
+  padding: 10px 20px 20px 20px;
 }
 
 .search-wrapper {
   margin-bottom: 20px;
+}
+
+.options-wrapper {
+  a {
+    margin-right: 8px;
+  }
 }
\ No newline at end of file
diff --git a/web/src/components/Modalx/index.less b/web/src/components/Modalx/index.less
new file mode 100644
index 0000000..6b03518
--- /dev/null
+++ b/web/src/components/Modalx/index.less
@@ -0,0 +1,17 @@
+.psw-set {
+  border-top: 1px solid #ccc;
+  padding-top: 20px;
+
+  .pws-label {
+    float: left;
+    line-height: 32px;
+  }
+
+  .psw-input {
+    width: 300px;
+  }
+}
+
+.enhance {
+  color: red;
+}
\ No newline at end of file
diff --git a/web/src/components/Modalx/index.tsx b/web/src/components/Modalx/index.tsx
new file mode 100644
index 0000000..16a7831
--- /dev/null
+++ b/web/src/components/Modalx/index.tsx
@@ -0,0 +1,49 @@
+/**
+ * TABLE COMPONENT WITH SEARCH
+ */
+import { Modal, Input, Tooltip } from 'antd';
+import * as React from 'react';
+import { ModalProps } from 'antd/lib/modal';
+import { ReactElement, useEffect } from 'react';
+import './index.less';
+
+const { useState } = React;
+
+export interface OKProps {
+  e: React.MouseEvent<HTMLElement>;
+  psw: string;
+  params?: any;
+}
+
+type ComProps = {
+  context?: number;
+  children?: ReactElement;
+  onOk?: (p: OKProps) => {};
+  params?: any;
+};
+
+const Comp = (props: ComProps & Omit<ModalProps, 'onOk'>) => {
+  const { params } = props;
+  const [psw, setPsw] = useState('');
+  const onOk = (e: React.MouseEvent<HTMLElement>) => {
+    props.onOk && props.onOk({ e, psw, params });
+  };
+
+  return (
+    <>
+      <Modal {...props} className="textWrap" width="60%" onOk={onOk}>
+        {props.children}
+        <div className="psw-set">
+          <label className="pws-label">机器授权:</label>
+          <Input
+            className="psw-input"
+            placeholder="请输入机器授权字段,验证操作权限"
+            onChange={e => setPsw(e.target.value)}
+          />
+        </div>
+      </Modal>
+    </>
+  );
+};
+
+export default Comp;
diff --git a/web/src/components/Tablex/index.tsx b/web/src/components/Tablex/index.tsx
index dc5e904..6e311ad 100644
--- a/web/src/components/Tablex/index.tsx
+++ b/web/src/components/Tablex/index.tsx
@@ -21,6 +21,7 @@ interface ComProps extends TableProps<any> {
   defaultSearchKey?: string;
   isTruePagination?: boolean;
   showSearch?: boolean;
+  searchWidth?: number;
 }
 
 const Comp = (props: ComProps) => {
@@ -32,6 +33,7 @@ const Comp = (props: ComProps) => {
     defaultSearchKey,
     isTruePagination,
     showSearch = true,
+    searchWidth = 8,
   } = props;
   const [filterKey, setFilterKey] = useState(defaultSearchKey);
   // 自动增加排序
@@ -83,7 +85,7 @@ const Comp = (props: ComProps) => {
     <>
       {showSearch && filterFnX && (
         <Row gutter={20} className="mb10">
-          <Col span={8}>
+          <Col span={searchWidth} style={{ padding: 0 }}>
             <Tooltip title={filterKey}>
               <Search
                 value={filterKey}
diff --git a/web/src/components/Tablex/tableFilterHelper.ts b/web/src/components/Tablex/tableFilterHelper.ts
new file mode 100644
index 0000000..0032e8f
--- /dev/null
+++ b/web/src/components/Tablex/tableFilterHelper.ts
@@ -0,0 +1,32 @@
+interface TableFilterHelperProp {
+  key: string;
+  targetArray: Array<any>;
+  srcArray: Array<any>;
+  filterList: Array<any>;
+  updateFunction?: (p: Array<any>) => void;
+}
+const tableFilterHelper = (p: TableFilterHelperProp): any[] => {
+  const { key, srcArray = [], filterList, updateFunction } = p;
+  const res: any[] = [];
+
+  if (key) {
+    srcArray.forEach(it => {
+      const tar = filterList.map(t => {
+        return it[t];
+      });
+      let isFilterRight = false;
+      tar.forEach(t => {
+        if ((t + '').indexOf(key) > -1) isFilterRight = true;
+      });
+      if (isFilterRight) {
+        res.push(it);
+      }
+    });
+  }
+
+  if (updateFunction) updateFunction(res);
+
+  return res;
+};
+
+export default tableFilterHelper;
diff --git a/web/src/configs/menus/index.tsx b/web/src/configs/menus/index.tsx
index 140f583..e689571 100644
--- a/web/src/configs/menus/index.tsx
+++ b/web/src/configs/menus/index.tsx
@@ -28,13 +28,14 @@ const menus: Route[] = [
     name: '配置管理',
     key: '/other',
     icon: <SettingOutlined />,
+    path: '/other',
     children: [
       {
-        path: '/hello',
+        path: '/broker',
         name: 'Broker列表',
       },
       {
-        path: '/user',
+        path: '/topic',
         name: 'topic列表',
       },
     ],
diff --git a/web/src/context/globalContext.ts b/web/src/context/globalContext.ts
index 34e7f06..0540e02 100644
--- a/web/src/context/globalContext.ts
+++ b/web/src/context/globalContext.ts
@@ -6,6 +6,7 @@ export interface GlobalContextProps {
   setCluster?: Function;
   breadMap?: BreadcrumbProps['breadcrumbMap'];
   setBreadMap?: Function;
+  userInfo?: any;
 }
 
 export default React.createContext<GlobalContextProps>({});
diff --git a/web/src/pages/Broker/index.less b/web/src/pages/Broker/index.less
new file mode 100644
index 0000000..e69de29
diff --git a/web/src/pages/Broker/index.tsx b/web/src/pages/Broker/index.tsx
new file mode 100644
index 0000000..644f3e2
--- /dev/null
+++ b/web/src/pages/Broker/index.tsx
@@ -0,0 +1,482 @@
+import React, { useContext, useState } from 'react';
+import GlobalContext from '@/context/globalContext';
+import Breadcrumb from '@/components/Breadcrumb';
+import Table from '@/components/Tablex';
+import Modal, { OKProps } from '@/components/Modalx';
+import {
+  Form,
+  Select,
+  Button,
+  Spin,
+  Switch,
+  Input,
+  Row,
+  Col,
+  message,
+} from 'antd';
+import { useImmer } from 'use-immer';
+import { useRequest } from '@/hooks';
+import tableFilterHelper from '@/components/Tablex/tableFilterHelper';
+import { boolean2Chinese } from '@/utils';
+import './index.less';
+
+declare type BrokerData = any[];
+interface BrokerResultData {
+  acceptPublish: string;
+  acceptSubscribe: string;
+  brokerId: number;
+  brokerIp: string;
+  brokerPort: number;
+  brokerTLSPort: number;
+  brokerVersion: string;
+  enableTLS: boolean;
+  isAutoForbidden: boolean;
+  isBrokerOnline: string;
+  isConfChanged: string;
+  isConfLoaded: string;
+  isRepAbnormal: boolean;
+  manageStatus: string;
+  runStatus: string;
+  subStatus: string;
+  [key: string]: any;
+}
+
+const { Option } = Select;
+const OPTIONS = [
+  {
+    value: 'online',
+    name: '上线',
+  },
+  {
+    value: 'offline',
+    name: '下线',
+  },
+  {
+    value: 'reload',
+    name: '重载',
+  },
+  {
+    value: 'delete',
+    name: '删除',
+  },
+];
+const OPTIONS_VALUES = OPTIONS.map(t => t.value);
+const queryBroker = (data: BrokerResultData) => ({
+  url: '/api/op_query/admin_query_broker_run_status',
+  data: data,
+});
+
+const Broker: React.FC = () => {
+  // column config
+  const columns = [
+    {
+      title: 'BrokerID',
+      dataIndex: 'brokerId',
+      fixed: 'left',
+    },
+    {
+      title: 'BrokerIP',
+      dataIndex: 'brokerIp',
+    },
+    {
+      title: 'BrokerPort',
+      dataIndex: 'brokerPort',
+    },
+    {
+      title: '管理状态',
+      dataIndex: 'manageStatus',
+    },
+    {
+      title: '运行状态',
+      dataIndex: 'runStatus',
+    },
+    {
+      title: '运行子状态',
+      dataIndex: 'subStatus',
+    },
+    {
+      title: '可发布',
+      dataIndex: 'acceptPublish',
+      render: (t: string, r: BrokerResultData) => {
+        return (
+          <Switch
+            checked={t === 'true'}
+            onChange={e => onSwitchChange(e, r, 'acceptPublish')}
+          />
+        );
+      },
+    },
+    {
+      title: '可订阅',
+      dataIndex: 'acceptSubscribe',
+      render: (t: string, r: BrokerResultData) => {
+        return (
+          <Switch
+            checked={t === 'true'}
+            onChange={e => onSwitchChange(e, r, 'acceptSubscribe')}
+          />
+        );
+      },
+    },
+    {
+      title: '配置变更',
+      dataIndex: 'isConfChanged',
+      render: (t: string) => boolean2Chinese(t),
+    },
+    {
+      title: '变更加载',
+      dataIndex: 'isConfLoaded',
+      render: (t: string) => boolean2Chinese(t),
+    },
+    {
+      title: 'broker注册',
+      dataIndex: 'isBrokerOnline',
+      render: (t: string) => boolean2Chinese(t),
+    },
+    {
+      title: '上线',
+      dataIndex: 'isBrokerOnline',
+      render: (t: string) => boolean2Chinese(t),
+    },
+    {
+      title: 'TLS端口',
+      dataIndex: 'brokerTLSPort',
+      render: (t: string) => boolean2Chinese(t),
+    },
+    {
+      title: '启用TLS',
+      dataIndex: 'enableTLS',
+      render: (t: boolean) => boolean2Chinese(t),
+    },
+    {
+      title: '上报异常',
+      dataIndex: 'isRepAbnormal',
+      render: (t: boolean) => boolean2Chinese(t),
+    },
+    {
+      title: '自动屏蔽',
+      dataIndex: 'isAutoForbidden',
+      render: (t: boolean) => boolean2Chinese(t),
+    },
+    {
+      title: '操作',
+      dataIndex: 'brokerIp',
+      fixed: 'right',
+      width: 180,
+      render: (t: string, r: any) => {
+        return (
+          <span className="options-wrapper">
+            {OPTIONS.map(t => (
+              <a key={t.value} onClick={() => onOptionsChange(t.value, r)}>
+                {t.name}
+              </a>
+            ))}
+          </span>
+        );
+      },
+    },
+  ];
+  const { breadMap, userInfo } = useContext(GlobalContext);
+  const [modalParams, updateModelParams] = useImmer<any>({});
+  const [filterData, updateFilterData] = useImmer<any>({});
+  const [selectBroker, setSelectBroker] = useState<any>([]);
+  const [brokerList, updateBrokerList] = useImmer<BrokerData>([]);
+  const [form] = Form.useForm();
+  const [newBrokerForm] = Form.useForm();
+  // init query
+  const { data, loading, run } = useRequest<any, BrokerData>(queryBroker, {
+    onSuccess: data => {
+      updateBrokerList(d => {
+        Object.assign(d, data);
+      });
+    },
+  });
+  // render funcs
+  const renderBrokerOptions = () => {
+    const columns = [
+      {
+        title: 'Broker',
+        render: (t: string, r: BrokerResultData) => {
+          return `${r.brokerId}#${r.brokerIp}:${r.brokerPort}`;
+        },
+      },
+      {
+        title: 'BrokerIP',
+        dataIndex: 'brokerIp',
+      },
+      {
+        title: '管理状态',
+        dataIndex: 'manageStatus',
+      },
+      {
+        title: '运行状态',
+        dataIndex: 'runStatus',
+      },
+      {
+        title: '运行子状态',
+        dataIndex: 'subStatus',
+      },
+      {
+        title: '可发布',
+        render: (t: string) => boolean2Chinese(t),
+      },
+      {
+        title: '可订阅',
+        render: (t: string) => boolean2Chinese(t),
+      },
+    ];
+    const dataSource = data.filter((t: BrokerResultData) =>
+      modalParams.params.includes(t.brokerId)
+    );
+    return (
+      <Table
+        columns={columns}
+        dataSource={dataSource}
+        rowKey="brokerId"
+      ></Table>
+    );
+  };
+  const renderNewBroker = () => {
+    const brokerFormArr = [
+      {
+        name: 'brokerId',
+        defaultValue: '0',
+      },
+      {
+        name: 'numPartitions',
+        defaultValue: '3',
+      },
+      {
+        name: 'brokerIP',
+        defaultValue: '',
+      },
+      {
+        name: 'brokerPort',
+        defaultValue: '8123',
+      },
+      {
+        name: 'deleteWhen',
+        defaultValue: '0 0 6,18 * * ?',
+      },
+      {
+        name: 'deletePolicy',
+        defaultValue: 'delete,168h',
+      },
+      {
+        name: 'unflushThreshold',
+        defaultValue: '1000',
+      },
+      {
+        name: 'unflushInterval',
+        defaultValue: '10000',
+      },
+      {
+        name: 'acceptPublish',
+        defaultValue: 'true',
+      },
+      {
+        name: 'acceptSubscribe',
+        defaultValue: 'true',
+      },
+    ];
+
+    return (
+      <Form form={newBrokerForm}>
+        <Row gutter={24}>
+          {brokerFormArr.map((t, index) => (
+            <Col span={12} key={'brokerFormArr' + index}>
+              <Form.Item
+                labelCol={{ span: 12 }}
+                label={t.name}
+                name={t.name}
+                initialValue={t.defaultValue}
+              >
+                <Input />
+              </Form.Item>
+            </Col>
+          ))}
+        </Row>
+      </Form>
+    );
+  };
+  const renderBrokerStateChange = () => {
+    const { params } = modalParams;
+
+    return (
+      <div>
+        请确认<span className="enhance">{params.option}</span> ID:{' '}
+        <span className="enhance">{params.id}</span> 的 Broker?
+      </div>
+    );
+  };
+
+  // events
+  const onOpenModal = (type: string, title: string, params?: any) => {
+    updateModelParams(m => {
+      m.type = type;
+      m.params = params;
+      Object.assign(m, {
+        params,
+        visible: type,
+        title,
+        onOk: (p: OKProps) => onModelOk(type, p),
+        onCancel: () =>
+          updateModelParams(m => {
+            m.visible = false;
+          }),
+      });
+    });
+  };
+  // table event
+  const onSwitchChange = (e: boolean, r: BrokerResultData, type: string) => {
+    const index = data.findIndex(
+      (t: BrokerResultData) => t.brokerId === r.brokerId
+    );
+    updateBrokerList(d => {
+      d[index][type] = e + '';
+    });
+    let option = '';
+    if (type === 'acceptPublish') {
+      option = e ? '发布' : '禁止发布';
+    } else if (type === 'acceptSubscribe') {
+      option = e ? '订阅' : '禁止订阅';
+    }
+
+    onOpenModal('brokerStateChange', `请确认操作`, { option, id: r.brokerId });
+  };
+  const onBrokerTableSelectChange = (p: any[], rows: any[]) => {
+    setSelectBroker(p);
+  };
+
+  // modal event
+  const onOptionsChange = (type: string, r?: BrokerResultData) => {
+    if (!r && !selectBroker.length) {
+      form.resetFields();
+      return message.error('批量操作至少选择一列!');
+    }
+    onOpenModal(
+      type,
+      `确认进行【${OPTIONS.find(t => t.value === type)?.name}】操作?`,
+      [r?.brokerId]
+    );
+  };
+  const onModelOk = (type: string, p: OKProps) => {
+    switch (type) {
+      case 'newBroker':
+        return newBroker(p);
+      default:
+        return brokerOptions(type, p);
+    }
+  };
+
+  const newBrokerQuery = useRequest<any, any>(
+    data => ({ url: '/api/op_modify/admin_add_broker_configure', ...data }),
+    { manual: true }
+  );
+  const newBroker = (p: OKProps) => {
+    const values = newBrokerForm.getFieldsValue();
+    newBrokerQuery.run({
+      data: {
+        ...values,
+        confModAuthToken: p.psw,
+        createUser: userInfo.userName,
+      },
+    });
+  };
+
+  const brokerOptionsQuery = useRequest<any, any>(
+    (url, data) => ({ url, ...data }),
+    { manual: true }
+  );
+  const brokerOptions = (type: string, p: OKProps) => {
+    const { params } = p;
+    brokerOptionsQuery.run(`/api/op_modify/admin_${type}_broker_configure`, {
+      data: {
+        brokerId: params ? params?.join(',') : selectBroker.join(','),
+        confModAuthToken: p.psw,
+        createUser: userInfo.userName,
+      },
+    });
+  };
+
+  return (
+    <Spin spinning={loading}>
+      <Breadcrumb breadcrumbMap={breadMap}></Breadcrumb>
+      <div className="main-container">
+        <div
+          className="search-wrapper"
+          style={{ float: 'right', marginRight: '-16px' }}
+        >
+          <Form form={form} layout={'inline'}>
+            <Form.Item label="批量操作" name="optionType">
+              <Select
+                style={{ width: 120 }}
+                onChange={(v: string) => onOptionsChange(v)}
+                placeholder="请选择操作"
+              >
+                {OPTIONS.map(t => (
+                  <Option value={t.value} key={t.value}>
+                    {t.name}
+                  </Option>
+                ))}
+              </Select>
+            </Form.Item>
+            <Form.Item>
+              <Button
+                type="primary"
+                onClick={() => onOpenModal('newBroker', '新建Broker')}
+                style={{ margin: '0 10px 0 10px' }}
+              >
+                新增
+              </Button>
+              <Button type="primary" onClick={() => run()}>
+                刷新
+              </Button>
+            </Form.Item>
+          </Form>
+        </div>
+        <Table
+          rowSelection={{ onChange: onBrokerTableSelectChange }}
+          columns={columns}
+          dataSource={brokerList}
+          rowKey="brokerId"
+          searchPlaceholder="请输入关键字搜索"
+          searchWidth={12}
+          dataSourceX={filterData.list}
+          scroll={{ x: 2500 }}
+          filterFnX={value =>
+            tableFilterHelper({
+              key: value,
+              srcArray: data,
+              targetArray: filterData.list,
+              updateFunction: res =>
+                updateFilterData(filterData => {
+                  filterData.list = res;
+                }),
+              filterList: [
+                'brokerId',
+                'brokerIp',
+                'brokerPort',
+                'runStatus',
+                'subStatus',
+                'manageStatus',
+              ],
+            })
+          }
+        ></Table>
+      </div>
+      <Modal {...modalParams}>
+        <div>
+          {modalParams.type &&
+            OPTIONS_VALUES.includes(modalParams.type) &&
+            renderBrokerOptions()}
+          {modalParams.type === 'newBroker' && renderNewBroker()}
+          {modalParams.type === 'brokerStateChange' &&
+            renderBrokerStateChange()}
+        </div>
+      </Modal>
+    </Spin>
+  );
+};
+
+export default Broker;
diff --git a/web/src/pages/Issue/consumeGroupDetail.tsx b/web/src/pages/Issue/consumeGroupDetail.tsx
index 9e54f42..8b2f562 100644
--- a/web/src/pages/Issue/consumeGroupDetail.tsx
+++ b/web/src/pages/Issue/consumeGroupDetail.tsx
@@ -2,6 +2,7 @@ import React, { useContext } from 'react';
 import GlobalContext from '@/context/globalContext';
 import Breadcrumb from '@/components/Breadcrumb';
 import Table from '@/components/Tablex';
+import tableFilterHelper from '@/components/Tablex/tableFilterHelper';
 import { Form, Input, Button, Spin } from 'antd';
 import { useImmer } from 'use-immer';
 import './index.less';
@@ -43,6 +44,7 @@ const ConsumeGroupDetail: React.FC = () => {
   const { breadMap } = useContext(GlobalContext);
   const [form] = Form.useForm();
   const [formValues, updateFormValues] = useImmer<any>({});
+  const [filterData, updateFilterData] = useImmer<any>({});
   const { data, loading, run } = useRequest<any, ConsumeGroupData>(
     () =>
       queryUser({
@@ -86,6 +88,20 @@ const ConsumeGroupDetail: React.FC = () => {
           columns={columns}
           dataSource={data?.list}
           rowKey="brokerAddr"
+          searchPlaceholder="请输入 broker地址/分区ID 搜索"
+          dataSourceX={filterData.list}
+          filterFnX={value =>
+            tableFilterHelper({
+              key: value,
+              srcArray: data?.list,
+              targetArray: filterData.list,
+              updateFunction: res =>
+                updateFilterData(filterData => {
+                  filterData.list = res;
+                }),
+              filterList: ['brokerAddr', 'partId'],
+            })
+          }
         ></Table>
       </div>
     </Spin>
diff --git a/web/src/router.tsx b/web/src/router.tsx
index 1b6a6e9..66e0cdc 100644
--- a/web/src/router.tsx
+++ b/web/src/router.tsx
@@ -14,10 +14,13 @@ import GlobalContext from '@/context/globalContext';
 const App = () => {
   const [cluster, setCluster] = useState();
   const [breadMap, setBreadMap] = useState();
+  const [userInfo, setUserInfo] = useState({
+    userName: 'webapi',
+  });
 
   return (
     <GlobalContext.Provider
-      value={{ cluster, setCluster, breadMap, setBreadMap }}
+      value={{ cluster, setCluster, breadMap, setBreadMap, userInfo }}
     >
       <Router>
         <Layout>
diff --git a/web/src/routes/index.tsx b/web/src/routes/index.tsx
index 032a633..7cbd3d6 100644
--- a/web/src/routes/index.tsx
+++ b/web/src/routes/index.tsx
@@ -10,8 +10,8 @@ const routes: RouteProps[] = [
     component: () => import('@/pages/Issue'),
   },
   {
-    path: '/hello',
-    component: () => import('@/pages/Other/Hello'),
+    path: '/broker',
+    component: () => import('@/pages/Broker'),
   },
   {
     path: '/user',
diff --git a/web/src/utils/index.ts b/web/src/utils/index.ts
index 0c6378b..aadcc68 100644
--- a/web/src/utils/index.ts
+++ b/web/src/utils/index.ts
@@ -27,3 +27,15 @@ export const isEmptyParam = (value: any): boolean => {
   // value为默认值
   return !value;
 };
+
+export const boolean2Chinese = (value: boolean | string): string => {
+  let v = false;
+  if (value === 'false') {
+    v = false;
+  } else if (value === 'true') {
+    v = true;
+  } else {
+    v = value as boolean;
+  }
+  return v === false ? '否' : '是';
+};

[incubator-inlong] 09/10: fix(request): request data handle

Posted by do...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dockerzhang pushed a commit to branch new-web-client
in repository https://gitbox.apache.org/repos/asf/incubator-inlong.git

commit 20ec6011c59f1f0052aeb9cc67b09e2184d361f7
Author: zakwu <12...@qq.com>
AuthorDate: Tue Jun 30 17:27:17 2020 +0800

    fix(request): request data handle
---
 web/src/hooks/index.ts | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/web/src/hooks/index.ts b/web/src/hooks/index.ts
index 488569c..8340c9e 100644
--- a/web/src/hooks/index.ts
+++ b/web/src/hooks/index.ts
@@ -32,14 +32,18 @@ axios.interceptors.response.use(
       return Promise.reject(data);
     }
 
-    // set object outside data into it
-    const res = Object.assign({}, data);
-    delete res.errCode;
-    delete res.errMsg;
-    res.data = Object.assign(res.data, {
-      ...res,
-    });
-    return res || [];
+    // admin_query_master_group_info interface design no good need handle
+    if (
+      Object.keys(data).includes('groupName') &&
+      Object.keys(data).includes('groupStatus')
+    ) {
+      data.data = {
+        data: data.data,
+        groupName: data.groupName,
+        groupStatus: data.groupStatus,
+      };
+    }
+    return data || [];
   },
   function(error) {
     return Promise.reject(error);

[incubator-inlong] 05/10: feat(broker):topic page complete

Posted by do...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dockerzhang pushed a commit to branch new-web-client
in repository https://gitbox.apache.org/repos/asf/incubator-inlong.git

commit 83d771eafcedb459362d52fe9fc7984bfaf40e50
Author: zakwu <12...@qq.com>
AuthorDate: Wed Jun 24 15:34:02 2020 +0800

    feat(broker):topic page complete
---
 web/src/constants/topic.ts                         |   9 +
 .../pages/Broker/{brokerDetail.tsx => detail.tsx}  |   8 +-
 web/src/pages/Broker/index.tsx                     |   6 +-
 web/src/pages/Other/Hello/index.tsx                |  70 -----
 web/src/pages/Other/Simple/index.tsx               |   5 -
 web/src/pages/Other/User/index.tsx                 |  78 ------
 web/src/pages/Topic/commonModal.tsx                | 311 +++++++++++++++++++++
 web/src/pages/Topic/detail.tsx                     |   1 +
 web/src/pages/Topic/index.less                     |   9 +
 web/src/pages/Topic/index.tsx                      | 250 +++++++++++++++++
 web/src/pages/Topic/query.tsx                      | 169 +++++++++++
 web/src/routes/index.tsx                           |  14 +-
 web/src/setupProxy.js                              |   3 +-
 13 files changed, 765 insertions(+), 168 deletions(-)

diff --git a/web/src/constants/topic.ts b/web/src/constants/topic.ts
new file mode 100644
index 0000000..2757340
--- /dev/null
+++ b/web/src/constants/topic.ts
@@ -0,0 +1,9 @@
+export const TOPIC_INFO_ZH_MAP = {
+  topicName: 'Topic',
+  infoCount: '配置Broker数',
+  totalCfgNumPart: '配置分区数',
+  totalRunNumPartCount: '运行分区数',
+  isSrvAcceptPublish: '可发布',
+  isSrvAcceptSubscribe: '可订阅',
+  enableAuthControl: "权限受控",
+};
\ No newline at end of file
diff --git a/web/src/pages/Broker/brokerDetail.tsx b/web/src/pages/Broker/detail.tsx
similarity index 98%
rename from web/src/pages/Broker/brokerDetail.tsx
rename to web/src/pages/Broker/detail.tsx
index 76cb696..deb3d30 100644
--- a/web/src/pages/Broker/brokerDetail.tsx
+++ b/web/src/pages/Broker/detail.tsx
@@ -25,7 +25,7 @@ declare type TopicQueryData = {
 
 const {TabPane} = Tabs;
 
-const BrokerDetail: React.FC = () => {
+const Detail: React.FC = () => {
   const { id } = useParams();
   const { breadMap } = useContext(GlobalContext);
   const [form] = Form.useForm();
@@ -198,9 +198,9 @@ const BrokerDetail: React.FC = () => {
   const onSwitchChange = (e: boolean, type: string) => {
     let option = '';
     if (type === 'acceptPublish') {
-      option = e ? '发布' : '禁止发布';
+      option = e ? '发布' : '禁止可发布';
     } else if (type === 'acceptSubscribe') {
-      option = e ? '订阅' : '禁止订阅';
+      option = e ? '订阅' : '禁止可订阅';
     }
 
     onOpenModal({
@@ -302,4 +302,4 @@ const BrokerDetail: React.FC = () => {
   );
 };
 
-export default BrokerDetail;
+export default Detail;
diff --git a/web/src/pages/Broker/index.tsx b/web/src/pages/Broker/index.tsx
index 2322384..bfd31d6 100644
--- a/web/src/pages/Broker/index.tsx
+++ b/web/src/pages/Broker/index.tsx
@@ -115,7 +115,7 @@ const Broker: React.FC = () => {
         return (
           <span className="options-wrapper">
             {OPTIONS.map(t => (
-              <a href="#" key={t.value} onClick={() => onOptionsChange(t.value, r)}>
+              <a key={t.value} onClick={() => onOptionsChange(t.value, r)}>
                 {t.name}
               </a>
             ))}
@@ -147,9 +147,9 @@ const Broker: React.FC = () => {
   const onSwitchChange = (e: boolean, r: BrokerResultData, type: string) => {
     let option = '';
     if (type === 'acceptPublish') {
-      option = e ? '发布' : '禁止发布';
+      option = e ? '发布' : '禁止可发布';
     } else if (type === 'acceptSubscribe') {
-      option = e ? '订阅' : '禁止订阅';
+      option = e ? '订阅' : '禁止可订阅';
     }
 
     onOpenModal({
diff --git a/web/src/pages/Other/Hello/index.tsx b/web/src/pages/Other/Hello/index.tsx
deleted file mode 100644
index c676c79..0000000
--- a/web/src/pages/Other/Hello/index.tsx
+++ /dev/null
@@ -1,70 +0,0 @@
-import React from 'react';
-import { useRedux } from '@/hooks';
-import { Button, Input } from 'antd';
-import { createStore, Provider } from '@reactseed/use-redux';
-
-interface TState {
-  name: string;
-  age: number;
-}
-
-interface TMethod {
-  updateName: (name: string) => void;
-  becomeOlder: () => void;
-}
-
-const cStore = createStore(() => ({
-  age: 20,
-  name: 'reactseed',
-}));
-
-const methods = (state: TState): TMethod => {
-  const { age } = state;
-  return {
-    updateName: (name: string) => {
-      state.name = name;
-    },
-    becomeOlder: () => {
-      state.age = age + 1;
-    },
-  };
-};
-
-const Hello: React.FC = () => {
-  const [state, method] = useRedux<TState, TMethod>(methods);
-
-  return (
-    <>
-      <p style={{ marginBottom: 16 }}>
-        This is an example using <b>useRedux</b>,See the section about
-        <a href="https://github.com/reactseed/use-redux">
-          @reactseed/use-redux
-        </a>
-        for more information.
-      </p>
-
-      <h1>
-        Hello {state.name} ({state.age})
-      </h1>
-
-      <Input
-        style={{ width: 240, marginRight: 16 }}
-        onChange={e => {
-          method.updateName(e.target.value);
-        }}
-        value={state.name}
-      />
-      <Button onClick={method.becomeOlder}>Older</Button>
-    </>
-  );
-};
-
-const HelloPage: React.FC = () => {
-  return (
-    <Provider store={cStore}>
-      <Hello />
-    </Provider>
-  );
-};
-
-export default HelloPage;
diff --git a/web/src/pages/Other/Simple/index.tsx b/web/src/pages/Other/Simple/index.tsx
deleted file mode 100644
index 2320982..0000000
--- a/web/src/pages/Other/Simple/index.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-import React from 'react';
-
-const Simple: React.FC = () => <div>Simple Page</div>;
-
-export default Simple;
diff --git a/web/src/pages/Other/User/index.tsx b/web/src/pages/Other/User/index.tsx
deleted file mode 100644
index dbe7668..0000000
--- a/web/src/pages/Other/User/index.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-import React from 'react';
-import { Table } from 'antd';
-import { TablePaginationConfig } from 'antd/lib/table/Table';
-import { useRequest } from '@/hooks';
-
-interface TQueryUserParams {
-  current?: number;
-  pageSize?: number;
-}
-
-interface TUser {
-  gender?: string;
-  email?: string;
-  name?: any;
-  [key: string]: any;
-}
-
-const queryUser = (data: TQueryUserParams) => ({
-  url: 'https://randomuser.me/api',
-  data: {
-    page: data.current,
-    results: data.pageSize,
-  },
-});
-
-const columns = [
-  {
-    title: 'Name',
-    dataIndex: 'name',
-    sorter: true,
-    render: (name: any) => `${name.first} ${name.last}`,
-  },
-  {
-    title: 'Gender',
-    dataIndex: 'gender',
-    filters: [
-      { text: 'Male', value: 'male' },
-      { text: 'Female', value: 'female' },
-    ],
-  },
-  {
-    title: 'Email',
-    dataIndex: 'email',
-  },
-];
-
-const UserPage: React.FC = () => {
-  const { data, loading, pagination } = useRequest<any, TUser>(queryUser, {
-    paginated: true,
-    formatResult: data => ({
-      list: data.results,
-      total: 200,
-    }),
-  });
-
-  return (
-    <>
-      <p style={{ marginBottom: 16 }}>
-        This is an example using <b>useRequest</b>,See the section about
-        <a href="https://github.com/reactseed/use-request">
-          @reactseed/use-request
-        </a>
-        for more information.
-      </p>
-
-      <Table
-        columns={columns}
-        rowKey={record => record.login.uuid}
-        dataSource={data?.list}
-        // useRequest returns that pagination and table's pagination parameter types are not compatible
-        pagination={pagination as TablePaginationConfig}
-        loading={loading}
-      />
-    </>
-  );
-};
-
-export default UserPage;
diff --git a/web/src/pages/Topic/commonModal.tsx b/web/src/pages/Topic/commonModal.tsx
new file mode 100644
index 0000000..7b28980
--- /dev/null
+++ b/web/src/pages/Topic/commonModal.tsx
@@ -0,0 +1,311 @@
+import {boolean2Chinese} from "@/utils";
+import Table from "@/components/Tablex";
+import {Col, Form, Input, message, Row} from "antd";
+import Modal, {OKProps} from "@/components/Modalx";
+import React, {useState} from "react";
+import Query from "@/pages/Topic/query";
+import {FormProps} from "antd/lib/form";
+
+export const OPTIONS = [
+  {
+    value: 'delete',
+    name: '删除',
+  },
+];
+export const OPTIONS_VALUES = OPTIONS.map(t => t.value);
+
+// interface
+export declare type TopicData = any[];
+export interface TopicResultData {
+  topicName: string,
+  infoCount: string,
+  totalCfgNumPart: string,
+  totalRunNumPartCount: string,
+  isSrvAcceptPublish: string|number,
+  isSrvAcceptSubscribe: string|number,
+  enableAuthControl: string|number,
+  [key: string]: any;
+}
+export interface TopicModalProps {
+  type: string;
+  title?: string;
+  updateFunction: (draft: any) => any;
+  params?: any;
+}
+interface ComProps {
+  modalParams: any;
+  data: any[];
+}
+// exports broker modal
+// render funcs
+const renderTopicOptions = (modalParams: any, dataSource: any[]) => {
+  const columns = [
+    {
+      title: 'Topic',
+      render: (t: string, r: TopicResultData) => {
+        return `${r.brokerId}#${r.brokerIp}:${r.brokerPort}`;
+      },
+    },
+    {
+      title: 'TopicIP',
+      dataIndex: 'brokerIp',
+    },
+    {
+      title: '管理状态',
+      dataIndex: 'manageStatus',
+    },
+    {
+      title: '运行状态',
+      dataIndex: 'runStatus',
+    },
+    {
+      title: '运行子状态',
+      dataIndex: 'subStatus',
+    },
+    {
+      title: '可发布',
+      render: (t: string) => boolean2Chinese(t),
+    },
+    {
+      title: '可订阅',
+      render: (t: string) => boolean2Chinese(t),
+    },
+  ];
+  return (
+    <Table
+      columns={columns}
+      dataSource={dataSource}
+      rowKey="brokerId"
+    />
+  );
+};
+const renderNewTopic = (form: any) => {
+  const brokerFormArr = [
+    {
+      name: 'topicName',
+      defaultValue: '',
+    },
+    {
+      name: 'numPartitions',
+      defaultValue: '3',
+    },
+    {
+      name: 'deleteWhen',
+      defaultValue: '0 0 6,18 * * ?',
+    },
+    {
+      name: 'deletePolicy',
+      defaultValue: 'delete,168h',
+    },
+    {
+      name: 'unflushThreshold',
+      defaultValue: '1000',
+    },
+    {
+      name: 'unflushInterval',
+      defaultValue: '10000',
+    },
+    {
+      name: 'acceptPublish',
+      defaultValue: 'true',
+    },
+    {
+      name: 'acceptSubscribe',
+      defaultValue: 'true',
+    },
+  ];
+
+  return (
+    <Form form={form}>
+      <Row gutter={24}>
+        {brokerFormArr.map((t, index) => (
+          <Col span={12} key={'brokerFormArr' + index}>
+            <Form.Item
+              labelCol={{ span: 12 }}
+              label={t.name}
+              name={t.name}
+              initialValue={t.defaultValue}
+            >
+              <Input />
+            </Form.Item>
+          </Col>
+        ))}
+      </Row>
+    </Form>
+  );
+};
+const renderChooseBroker = (modalParams: any) => {
+  let {params} = modalParams;
+  const columns = [
+    {
+      title: 'Broker',
+      render: (t: string, r: TopicResultData) => {
+        return `${r.brokerId}#${r.brokerIp}:${r.brokerPort}`;
+      },
+    },
+    {
+      title: '实例数',
+      dataIndex: 'runInfo.totalTopicStoreNum',
+    },
+    {
+      title: '当前运行状态',
+      dataIndex: 'runInfo.brokerManageStatus',
+    },
+    {
+      title: '可发布',
+      dataIndex: 'runInfo.acceptPublish',
+      render: (t: string) => boolean2Chinese(t),
+    },
+    {
+      title: '可订阅',
+      dataIndex: 'runInfo.acceptSubscribe',
+      render: (t: string) => boolean2Chinese(t),
+    },
+  ];
+  const onChangeSelect = (p: any) => {
+    selectBroker = p;
+  };
+  return (
+    <Table
+      rowSelection={{ onChange: onChangeSelect }}
+      columns={columns}
+      dataSource={params.data}
+      rowKey="brokerId"
+    />
+  );
+};
+const renderEditTopic = (modalParams: any, form: FormProps['form']) => {
+  const {params: p} = modalParams;
+  const pickArr = ['numPartitions', 'unflushThreshold', 'unflushInterval', 'deleteWhen', 'deletePolicy', 'acceptPublish', 'acceptSubscribe'];
+  let brokerFormArr : Array<{
+    name: string;
+    defaultValue: string;
+  }> = [];
+  pickArr.forEach(t => {
+    brokerFormArr.push({
+      name: t,
+      defaultValue: p[t]
+    })
+  })
+
+  return (
+    <Form form={form}>
+      <Row gutter={24}>
+        {brokerFormArr.map((t, index) => (
+          <Col span={12} key={'brokerFormArr' + index}>
+            <Form.Item
+              labelCol={{ span: 12 }}
+              label={t.name}
+              name={t.name}
+              initialValue={t.defaultValue}
+            >
+              <Input />
+            </Form.Item>
+          </Col>
+        ))}
+      </Row>
+    </Form>
+  );
+};
+const renderTopicStateChange = (modalParams: any) => {
+  const { params } = modalParams;
+
+  return (
+    <div>
+      请确认<span className="enhance">{params.option}</span> 以下broker列表的 topic :
+      <span className="enhance">({params.topicName})</span> 的 Topic?
+      {renderChooseBroker(modalParams)}
+    </div>
+  );
+};
+const renderDeleteTopic = (modalParams: any) => {
+  const { params } = modalParams;
+
+  return (
+    <div>
+      请确认<span className="enhance">删除</span> 以下broker列表的 topic :
+      <span className="enhance">({params.topicName})</span> 吗?
+      {renderChooseBroker(modalParams)}
+    </div>
+  );
+};
+const renderAuthorizeControlChange = (modalParams: any) => {
+  const { params } = modalParams;
+
+  return (
+    <div>
+      请确认<span className="enhance">{params.value ? '启动' : '关闭'}topic<span className="enhance">({params.topicName})</span>的消费组授权控制</span>吗?
+    </div>
+  );
+};
+export const onOpenModal = (p: TopicModalProps) => {
+  const {type, title, updateFunction, params} = p;
+  updateFunction((m: any) => {
+    m.type = type;
+    m.params = params;
+    Object.assign(m, {
+      params,
+      visible: type,
+      title,
+      onOk: (p: OKProps) => {
+        updateFunction((m: any) => {
+          if(type === 'newTopic' || type === 'editTopic') {
+            p.params = Object.assign(f && f.getFieldsValue(), {
+              callback: p.params.callback
+            });
+          }
+
+          if(type === 'chooseBroker' || type === 'topicStateChange' || type === 'deleteTopic') {
+            if(!selectBroker.length) {
+              message.error('至少选择一列!');
+              return;
+            }
+
+            // end
+            if(type === 'chooseBroker') {
+              m.query = 'endChooseBroker';
+            }
+            p.params = Object.assign({}, p.params, {
+              selectBroker
+            })
+          }
+
+          m.okParams = p;
+          m.isOk = Date.now();
+        })
+      },
+      onCancel: () =>
+        updateFunction((m: any) => {
+          m.visible = false;
+        }),
+    });
+  });
+};
+
+let selectBroker: any[] = [];
+let f: FormProps['form'];
+const Comp = (props: ComProps) => {
+  const {modalParams, data} = props;
+  const [form] = Form.useForm();
+  f = form;
+
+  return (
+    <Modal {...modalParams}>
+      <div>
+        {modalParams.type &&
+        OPTIONS_VALUES.includes(modalParams.type) && renderTopicOptions(modalParams, data.filter((t: TopicResultData) =>
+          modalParams.params.includes(t.brokerId)
+        ))}
+        {modalParams.type === 'newTopic' && renderNewTopic(form)}
+        {modalParams.type === 'chooseBroker' && renderChooseBroker(modalParams)}
+        {modalParams.type === 'editTopic' && renderEditTopic(modalParams, form)}
+        {modalParams.type === 'topicStateChange' && renderTopicStateChange(modalParams)}
+        {modalParams.type === 'deleteTopic' && renderDeleteTopic(modalParams)}
+        {modalParams.type === 'authorizeControl' && renderAuthorizeControlChange(modalParams)}
+      </div>
+     <Query fire={modalParams.isOk} params={modalParams.okParams} type={modalParams.visible && (modalParams.query || modalParams.type)} />
+    </Modal>
+  )
+};
+
+export default Comp;
\ No newline at end of file
diff --git a/web/src/pages/Topic/detail.tsx b/web/src/pages/Topic/detail.tsx
new file mode 100644
index 0000000..693da49
--- /dev/null
+++ b/web/src/pages/Topic/detail.tsx
@@ -0,0 +1 @@
+export {}
\ No newline at end of file
diff --git a/web/src/pages/Topic/index.less b/web/src/pages/Topic/index.less
new file mode 100644
index 0000000..c0e07eb
--- /dev/null
+++ b/web/src/pages/Topic/index.less
@@ -0,0 +1,9 @@
+.broker-detail-options-wrapper {
+  position: absolute;
+  top: 0;
+  right: 0;
+
+  .mr10 {
+    margin-right: 10px;
+  }
+}
\ No newline at end of file
diff --git a/web/src/pages/Topic/index.tsx b/web/src/pages/Topic/index.tsx
new file mode 100644
index 0000000..d5b43c8
--- /dev/null
+++ b/web/src/pages/Topic/index.tsx
@@ -0,0 +1,250 @@
+import React, { useContext } from 'react';
+import GlobalContext from '@/context/globalContext';
+import Breadcrumb from '@/components/Breadcrumb';
+import Table from '@/components/Tablex';
+import { Form, Button, Spin, Switch} from 'antd';
+import { useImmer } from 'use-immer';
+import { useRequest } from '@/hooks';
+import tableFilterHelper from '@/components/Tablex/tableFilterHelper';
+import { boolean2Chinese, transParamsWithConstantsMap } from '@/utils';
+import {TOPIC_INFO_ZH_MAP} from '@/constants/topic';
+import './index.less';
+import {Link} from "react-router-dom";
+import CommonModal, {OPTIONS, onOpenModal, TopicResultData, TopicData} from './commonModal'
+
+const Topic: React.FC = () => {
+  // column config
+  const columns = [
+    {
+      title: transParamsWithConstantsMap(TOPIC_INFO_ZH_MAP,'topicName'),
+      dataIndex: 'topicName',
+      render: (t: Array<any>) => <Link to={'/topic/' + t}>{t}</Link>,
+    },
+    {
+      title: transParamsWithConstantsMap(TOPIC_INFO_ZH_MAP,'infoCount'),
+      dataIndex: 'infoCount',
+    },
+    {
+      title: transParamsWithConstantsMap(TOPIC_INFO_ZH_MAP,'totalCfgNumPart'),
+      dataIndex: 'totalCfgNumPart',
+    },
+    {
+      title: transParamsWithConstantsMap(TOPIC_INFO_ZH_MAP,'totalRunNumPartCount'),
+      dataIndex: 'totalRunNumPartCount',
+    },
+    {
+      title: transParamsWithConstantsMap(TOPIC_INFO_ZH_MAP,'isSrvAcceptPublish'),
+      dataIndex: 'isSrvAcceptPublish',
+      render: (t: boolean, r: TopicResultData) => {
+        return (
+          <Switch
+            checked={t}
+            onChange={e => onSwitchChange(e, r, 'isSrvAcceptPublish')}
+          />
+        );
+      },
+    },
+    {
+      title: transParamsWithConstantsMap(TOPIC_INFO_ZH_MAP,'isSrvAcceptSubscribe'),
+      dataIndex: 'isSrvAcceptSubscribe',
+      render: (t: boolean, r: TopicResultData) => {
+        return (
+          <Switch
+            checked={t}
+            onChange={e => onSwitchChange(e, r, 'isSrvAcceptSubscribe')}
+          />
+        );
+      },
+    },
+    {
+      title: transParamsWithConstantsMap(TOPIC_INFO_ZH_MAP,'enableAuthControl'),
+      dataIndex: 'authData.enableAuthControl',
+      render: (t: boolean, r: TopicResultData) => {
+        return (
+          <Switch
+            checked={r.authData.enableAuthControl}
+            onChange={e => onAuthorizeControl(e, r)}
+          />
+        );
+      },
+    },
+    {
+      title: '操作',
+      dataIndex: 'topicIp',
+      render: (t: string, r: any) => {
+        return <a onClick={() => onDelete(r)}>删除</a>
+      }
+    }
+  ];
+  const { breadMap } = useContext(GlobalContext);
+  const [modalParams, updateModelParams] = useImmer<any>({});
+  const [filterData, updateFilterData] = useImmer<any>({});
+  const [topicList, updateTopicList] = useImmer<TopicData>([]);
+  const [form] = Form.useForm();
+  // init query
+  const { data, loading, run } = useRequest<any, TopicData>((data: TopicResultData) => ({
+    url: '/api/op_query/admin_query_topic_info',
+    data: data,
+  }), {
+    cacheKey: 'topicList',
+    onSuccess: data => {
+      updateTopicList(d => {
+        Object.assign(d, data);
+      });
+    },
+  });
+
+  // table event
+  // acceptSubscribe && acceptPublish options
+  const queryBrokerListByTopicNameQuery = useRequest<any, any>(
+    data => ({ url: '/api/op_query/admin_query_topic_info', ...data }),
+    { manual: true }
+  );
+  const onSwitchChange = (e: boolean, r: TopicResultData, type: string) => {
+    let option = '';
+    if (type === 'isSrvAcceptPublish') {
+      option = e ? '发布' : '禁止可发布';
+    } else if (type === 'isSrvAcceptSubscribe') {
+      option = e ? '订阅' : '禁止可订阅';
+    }
+
+    queryBrokerListByTopicNameQuery.run({
+      data: {
+        topicName: r.topicName,
+        brokerId: ''
+      },
+    }).then((d: TopicResultData) => {
+      onOpenModal({
+        type: 'topicStateChange',
+        title: `请确认操作`,
+        updateFunction: updateModelParams,
+        params: {
+          option,
+          value: e,
+          topicName: r.topicName,
+          data: d[0].topicInfo,
+          type,
+          callback: () => {
+            const index = data.findIndex(
+              (t: TopicResultData) => t.topicName === r.topicName
+            );
+            updateTopicList(d => {
+              d[index][type] = e + '';
+            });
+          }
+        },
+      });
+    });
+  };
+  // author
+  const onAuthorizeControl = (e: boolean, r: TopicResultData) => {
+    const option = e ? '发布' : '禁止可发布';
+    onOpenModal({
+      type: 'authorizeControl',
+      title: `请确认操作`,
+      updateFunction: updateModelParams,
+      params: {
+        option,
+        value: e,
+        topicName: r.topicName,
+        callback: () => {
+          debugger
+          const index = data.findIndex(
+            (t: TopicResultData) => t.topicName === r.topicName
+          );
+          updateTopicList(d => {
+            d[index]['authData']['enableAuthControl'] = e + '';
+          });
+        }
+      },
+    });
+  }
+  // new topic
+  const onNewTopic = () => {
+    onOpenModal({
+      type: 'newTopic', title: '新建Topic', updateFunction: updateModelParams, params: {
+        callback: (d: any) => {
+          onOpenModal({
+            type: 'chooseBroker', title: '选择【新增】broker列表', updateFunction: updateModelParams, params: {
+              data: d,
+              callback: () => {
+                onOpenModal({type: 'close', updateFunction: updateModelParams})
+              },
+            }
+          });
+        }
+      }
+    })
+  };
+  // delete
+  const onDelete = (r: TopicResultData) => {
+    queryBrokerListByTopicNameQuery.run({
+      data: {
+        topicName: r.topicName,
+        brokerId: ''
+      },
+    }).then((d: TopicResultData) => {
+      onOpenModal({
+        type: 'deleteTopic',
+        title: `请确认操作`,
+        updateFunction: updateModelParams,
+        params: {
+          topicName: r.topicName,
+          data: d[0].topicInfo,
+        },
+      });
+    });
+  };
+
+  return (
+    <Spin spinning={loading}>
+      <Breadcrumb breadcrumbMap={breadMap} />
+      <div className="main-container">
+        <div
+          className="search-wrapper"
+          style={{ float: 'right', marginRight: '-16px' }}
+        >
+          <Form form={form} layout={'inline'}>
+            <Form.Item>
+              <Button
+                type="primary"
+                onClick={() => onNewTopic()}
+                style={{ margin: '0 10px 0 10px' }}
+              >
+                新增
+              </Button>
+              <Button type="primary" onClick={() => run()}>
+                刷新
+              </Button>
+            </Form.Item>
+          </Form>
+        </div>
+        <Table
+          columns={columns}
+          dataSource={topicList}
+          rowKey="topicName"
+          searchPlaceholder="请输入topicName查询"
+          searchWidth={12}
+          dataSourceX={filterData.list}
+          filterFnX={value =>
+            tableFilterHelper({
+              key: value,
+              srcArray: data,
+              targetArray: filterData.list,
+              updateFunction: res =>
+                updateFilterData(filterData => {
+                  filterData.list = res;
+                }),
+              filterList: [
+                'topicName',
+              ],
+            })
+          }
+        />
+      </div>
+      <CommonModal modalParams={modalParams} data={data} />
+    </Spin>
+  );
+};
+
+export default Topic;
diff --git a/web/src/pages/Topic/query.tsx b/web/src/pages/Topic/query.tsx
new file mode 100644
index 0000000..13a4570
--- /dev/null
+++ b/web/src/pages/Topic/query.tsx
@@ -0,0 +1,169 @@
+import * as React from 'react';
+import './index.less';
+import {OKProps} from "@/components/Modalx";
+import {useRequest} from "@/hooks";
+import {useContext, useEffect} from "react";
+import GlobalContext from "@/context/globalContext";
+
+interface ComProps {
+  fire: string;
+  params: any;
+  type: string;
+}
+
+let newObjectTemp: string = '';
+const Comp = (props: ComProps) => {
+  const {fire} = props;
+  const { userInfo } = useContext(GlobalContext);
+  useEffect(() => {
+    const {params, type} = props;
+    dispatchAction(type, params);
+  }, [fire]);
+
+  const dispatchAction = (type: string, p: OKProps) => {
+    if(!fire) return null;
+    let promise;
+    switch (type) {
+      case 'newTopic':
+        promise = newTopic(p);
+        break;
+      case 'endChooseBroker':
+        promise = endChooseBroker(p);
+        break;
+      case 'editTopic':
+        promise = editTopic(p);
+        break;
+      case 'topicStateChange':
+        promise = topicStateChange(type, p);
+        break;
+      case 'authorizeControl':
+        promise = authorizeControl(type, p);
+        break;
+      case 'deleteTopic':
+        promise = deleteTopic(type, p);
+        break;
+    }
+
+    promise && promise.then(t => {
+      const {callback} = p.params;
+      if(t.statusCode !== 0 && callback) callback(t);
+    })
+  };
+
+  const newTopicQuery = useRequest<any, any>(
+    data => ({ url: '/api/op_query/admin_query_broker_topic_config_info', ...data }),
+    { manual: true }
+  );
+  const newTopic = (p: OKProps) => {
+    newObjectTemp = JSON.stringify(p.params);
+    return newTopicQuery.run({
+      data: {
+        topicName: '',
+        brokerId: ''
+      },
+    });
+  };
+
+  const endChooseBrokerQuery = useRequest<any, any>(
+    data => ({ url: '/api/op_modify/admin_add_new_topic_record', ...data }),
+    { manual: true }
+  );
+  const endChooseBroker = (p: OKProps) => {
+    const topicParams = JSON.parse(newObjectTemp);
+    const {params} = p;
+    return endChooseBrokerQuery.run({
+      data: {
+        borkerId: params.selectBroker.join(','),
+        confModAuthToken: p.psw,
+        ...topicParams
+      },
+    });
+  };
+
+  const updateTopicQuery = useRequest<any, any>(
+    data => ({ url: '/api/op_modify/admin_update_broker_configure', ...data }),
+    { manual: true }
+  );
+  const editTopic = (p: OKProps) => {
+    const {params} = p;
+    return updateTopicQuery.run({
+      data: {
+        ...params,
+        confModAuthToken: p.psw,
+        createUser: userInfo.userName,
+      },
+    });
+  };
+
+  const deleteTopicQuery = useRequest<any, any>(
+    (url, data) => ({ url, ...data }),
+    { manual: true }
+  );
+  const deleteTopic = (type: string, p: OKProps) => {
+    const { params } = p;
+    return deleteTopicQuery.run(`/api/op_modify/admin_delete_topic_info`, {
+      data: {
+        brokerId: params.selectBroker.join(','),
+        confModAuthToken: p.psw,
+        modifyUser: userInfo.userName,
+        topicName: params.topicName
+      },
+    });
+  };
+
+  const topicStateChangeQuery = useRequest<any, any>(
+    (url, data) => ({ url, ...data }),
+    { manual: true }
+  );
+  const topicStateChange = (type: string, p: OKProps) => {
+    const { params } = p;
+    let data: {
+      [key: string]: any;
+    };
+
+    data = {
+      brokerId: params.selectBroker.join([',']),
+      confModAuthToken: p.psw,
+      modifyUser: userInfo.userName,
+      topicName: params.topicName
+    }
+    if(params.type === 'isSrvAcceptPublish') {
+      data.acceptPublish = params.value;
+    }
+    if(params.type === 'isSrvAcceptSubscribe') {
+      data.acceptSubscribe = params.value;
+    }
+
+    return topicStateChangeQuery.run(`/api/op_modify/admin_modify_topic_info`, {
+      data,
+    });
+  };
+
+  const authorizeControlQuery = useRequest<any, any>(
+    (url, data) => ({ url, ...data }),
+    { manual: true }
+  );
+  const authorizeControl = (type: string, p: OKProps) => {
+    const { params } = p;
+    let data: {
+      [key: string]: any;
+    };
+
+    data = {
+      confModAuthToken: p.psw,
+      topicName: params.topicName,
+      isEnable: params.value,
+      modifyUser: userInfo.userName,
+    }
+
+    return authorizeControlQuery.run(`/api/op_modify/admin_set_topic_authorize_control`, {
+      data,
+    });
+  };
+
+  return (
+    <></>
+  );
+};
+
+export default Comp;
diff --git a/web/src/routes/index.tsx b/web/src/routes/index.tsx
index c05340f..7fce665 100644
--- a/web/src/routes/index.tsx
+++ b/web/src/routes/index.tsx
@@ -11,19 +11,19 @@ const routes: RouteProps[] = [
   },
   {
     path: '/broker/:id',
-    component: () => import('@/pages/Broker/brokerDetail'),
+    component: () => import('@/pages/Broker/detail'),
   },
   {
     path: '/broker',
     component: () => import('@/pages/Broker'),
   },
+  // {
+  //   path: '/topic/:id',
+  //   component: () => import('@/pages/Topic/detail'),
+  // },
   {
-    path: '/user',
-    component: () => import('@/pages/Other/User'),
-  },
-  {
-    path: '/simple',
-    component: () => import('@/pages/Other/Simple'),
+    path: '/topic',
+    component: () => import('@/pages/Topic'),
   },
   {
     component: () => import('@/pages/NotFound'),
diff --git a/web/src/setupProxy.js b/web/src/setupProxy.js
index 3496dd6..b2f9c72 100644
--- a/web/src/setupProxy.js
+++ b/web/src/setupProxy.js
@@ -4,8 +4,9 @@ const { createProxyMiddleware } = require('http-proxy-middleware');
 module.exports = function(app) {
   app.use(
     createProxyMiddleware('/webapi.htm', {
+      target: ' http://9.56.46.168:8080',
       // target: 'http://10.224.148.145:8080',
-      target: 'http://10.215.131.92:8080',
+      // target: 'http://10.215.131.92:8080',
       changeOrigin: true,
       ws: true,
     })

[incubator-inlong] 01/10: feat(*): rebuild console

Posted by do...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dockerzhang pushed a commit to branch new-web-client
in repository https://gitbox.apache.org/repos/asf/incubator-inlong.git

commit 95f9b51a6dbfd2ecba8537e7bc8886ca2e4e6766
Author: zakwu <12...@qq.com>
AuthorDate: Wed Jun 10 17:50:10 2020 +0800

    feat(*): rebuild console
---
 web/.env                                 |     2 +
 web/.eslintignore                        |     5 +
 web/.eslintrc                            |    26 +
 web/.gitignore                           |    26 +
 web/.prettierrc                          |     4 +
 web/.stylelintrc                         |     3 +
 web/README.md                            |    33 +
 web/config-overrides.js                  |    52 +
 web/mock/_constant.js                    |     3 +
 web/mock/app.js                          |     6 +
 web/package-lock.json                    | 20318 +++++++++++++++++++++++++++++
 web/package.json                         |   108 +
 web/public/favicon.ico                   |   Bin 0 -> 1226 bytes
 web/public/index.html                    |    43 +
 web/public/logo192.png                   |   Bin 0 -> 33077 bytes
 web/public/logo512.png                   |   Bin 0 -> 9664 bytes
 web/public/manifest.json                 |    24 +
 web/public/robots.txt                    |     3 +
 web/src/components/Breadcrumb/index.less |     8 +
 web/src/components/Breadcrumb/index.tsx  |    38 +
 web/src/components/Layout/index.less     |    11 +
 web/src/components/Layout/index.tsx      |    76 +
 web/src/components/Tablex/index.less     |    16 +
 web/src/components/Tablex/index.tsx      |   110 +
 web/src/components/index.tsx             |     3 +
 web/src/configs/index.ts                 |     3 +
 web/src/configs/menus/index.tsx          |    42 +
 web/src/context/globalContext.ts         |    11 +
 web/src/defaultSettings.js               |     6 +
 web/src/hooks/index.ts                   |     5 +
 web/src/index.tsx                        |    11 +
 web/src/pages/Issue/index.less           |     2 +
 web/src/pages/Issue/index.tsx            |    16 +
 web/src/pages/NotFound/index.tsx         |     5 +
 web/src/pages/Other/Hello/index.tsx      |    70 +
 web/src/pages/Other/Simple/index.tsx     |     5 +
 web/src/pages/Other/User/index.tsx       |    78 +
 web/src/react-app-env.d.ts               |     1 +
 web/src/router.tsx                       |    41 +
 web/src/routes/index.tsx                 |    26 +
 web/src/serviceWorker.ts                 |   146 +
 web/src/setupProxy.js                    |    12 +
 web/src/store/global.ts                  |    30 +
 web/src/typings/index.ts                 |     1 +
 web/src/typings/router.ts                |    14 +
 web/src/utils/index.ts                   |    29 +
 web/tsconfig.json                        |    33 +
 web/tsconfig.paths.json                  |     8 +
 48 files changed, 21513 insertions(+)

diff --git a/web/.env b/web/.env
new file mode 100644
index 0000000..936a9dc
--- /dev/null
+++ b/web/.env
@@ -0,0 +1,2 @@
+PORT=3000
+SKIP_PREFLIGHT_CHECK=true
diff --git a/web/.eslintignore b/web/.eslintignore
new file mode 100644
index 0000000..6bba8e4
--- /dev/null
+++ b/web/.eslintignore
@@ -0,0 +1,5 @@
+node_modules/**
+dist/**
+public/**
+src/serviceWorker.ts
+mock
diff --git a/web/.eslintrc b/web/.eslintrc
new file mode 100644
index 0000000..7abddfd
--- /dev/null
+++ b/web/.eslintrc
@@ -0,0 +1,26 @@
+{
+  "extends": [
+    "plugin:@typescript-eslint/recommended",
+    "react-app",
+    "plugin:prettier/recommended"
+  ],
+  "plugins": ["@typescript-eslint", "react", "prettier"],
+  "env": {
+    "browser": true,
+    "node": true,
+    "mocha": true
+  },
+  "globals": {
+    "Babel": true,
+    "React": true
+  },
+  "settings": {
+    "react": {
+      "version": "detect"
+    }
+  },
+  "rules": {
+    "@typescript-eslint/no-explicit-any": 0,
+    "@typescript-eslint/explicit-function-return-type": 0
+  }
+}
diff --git a/web/.gitignore b/web/.gitignore
new file mode 100644
index 0000000..448f7e5
--- /dev/null
+++ b/web/.gitignore
@@ -0,0 +1,26 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# production
+/build
+
+# misc
+.DS_Store
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+package-lock.json
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+yarn.lock
+.history
diff --git a/web/.prettierrc b/web/.prettierrc
new file mode 100644
index 0000000..c1a6f66
--- /dev/null
+++ b/web/.prettierrc
@@ -0,0 +1,4 @@
+{
+  "singleQuote": true,
+  "trailingComma": "es5"
+}
diff --git a/web/.stylelintrc b/web/.stylelintrc
new file mode 100644
index 0000000..2e8ff58
--- /dev/null
+++ b/web/.stylelintrc
@@ -0,0 +1,3 @@
+{
+  "extends": ["stylelint-config-standard", "stylelint-config-prettier"]
+}
diff --git a/web/README.md b/web/README.md
new file mode 100644
index 0000000..d96c9e5
--- /dev/null
+++ b/web/README.md
@@ -0,0 +1,33 @@
+# web
+This project was bootstrapped with [React Seed](https://github.com/reactseed/reactseed).
+
+## Available Scripts
+Inside the newly created project, you can run some built-in commands:
+
+### `npm start` or `yarn start`
+
+Runs the app in development mode. 
+Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
+
+The page will reload if you make edits.
+You will also see any lint errors in the console.
+
+### `npm test` or `yarn test`
+
+Launches the test runner in the interactive watch mode.
+See the section about [running tests](https://create-react-app.dev/docs/running-tests/) for more information.
+
+### `npm run build` or `yarn build`
+
+Builds the app for production to the build folder.
+It correctly bundles React in production mode and optimizes the build for the best performance.
+
+The build is minified and the filenames include the hashes.
+Your app is ready to be deployed!
+
+See the section about [deployment](https://create-react-app.dev/docs/deployment/) for more information.
+
+### `npm run analyze` or `yarn analyze`
+
+Analyzes JavaScript bundles using the source maps.
+> You need to run `npm run build` or `yarn build` before analysis.
diff --git a/web/config-overrides.js b/web/config-overrides.js
new file mode 100644
index 0000000..bb8515b
--- /dev/null
+++ b/web/config-overrides.js
@@ -0,0 +1,52 @@
+/* eslint-disable @typescript-eslint/no-var-requires */
+const path = require('path');
+const webpack = require('webpack');
+const devServer = require('@reactseed/devserver');
+const AntdDayjsWebpackPlugin = require('antd-dayjs-webpack-plugin');
+const {
+  override,
+  addWebpackAlias,
+  addLessLoader,
+  overrideDevServer,
+  addWebpackPlugin,
+  fixBabelImports,
+  addBabelPlugin,
+} = require('customize-cra');
+const nodeModulesPath = path.resolve(__dirname, 'node_modules');
+const nodeModules = pkg => path.resolve(nodeModulesPath, pkg);
+
+module.exports = {
+  webpack: override(
+    addBabelPlugin('react-hot-loader/babel'),
+    addLessLoader({
+      javascriptEnabled: true,
+    }),
+    addWebpackAlias({
+      '@': path.resolve(__dirname, 'src'),
+    }),
+    fixBabelImports('antd', {
+      libraryDirectory: 'lib',
+      style: 'css',
+    }),
+    addWebpackPlugin(
+      new AntdDayjsWebpackPlugin(),
+      new webpack.HotModuleReplacementPlugin()
+    ),
+    config => {
+      if (config.mode === 'development') {
+        config.resolve.alias['react-dom'] = path.resolve(
+          __dirname,
+          'node_modules/@hot-loader/react-dom'
+        );
+        config.entry.unshift(nodeModules('react-hot-loader/patch'));
+      }
+      return config;
+    }
+  ),
+  devServer: overrideDevServer(devServer, config => {
+    config.inline = true;
+    // eslint-disable-next-line no-undef
+    Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 10000);
+    return config;
+  }),
+};
diff --git a/web/mock/_constant.js b/web/mock/_constant.js
new file mode 100644
index 0000000..286afb4
--- /dev/null
+++ b/web/mock/_constant.js
@@ -0,0 +1,3 @@
+module.exports = {
+  apiPrefix: '/api',
+};
diff --git a/web/mock/app.js b/web/mock/app.js
new file mode 100644
index 0000000..6a109a8
--- /dev/null
+++ b/web/mock/app.js
@@ -0,0 +1,6 @@
+const { apiPrefix } = require('./_constant');
+const packageJSON = require('../package.json');
+
+module.exports = {
+  [`GET ${apiPrefix}/app`]: packageJSON,
+};
diff --git a/web/package-lock.json b/web/package-lock.json
new file mode 100644
index 0000000..8eba5d6
--- /dev/null
+++ b/web/package-lock.json
@@ -0,0 +1,20318 @@
+{
+  "name": "web",
+  "version": "0.1.0",
+  "lockfileVersion": 1,
+  "requires": true,
+  "dependencies": {
+    "@ant-design/colors": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-3.2.2.tgz",
+      "integrity": "sha512-YKgNbG2dlzqMhA9NtI3/pbY16m3Yl/EeWBRa+lB1X1YaYxHrxNexiQYCLTWO/uDvAjLFMEDU+zR901waBtMtjQ==",
+      "requires": {
+        "tinycolor2": "^1.4.1"
+      }
+    },
+    "@ant-design/css-animation": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/@ant-design/css-animation/-/css-animation-1.7.2.tgz",
+      "integrity": "sha512-bvVOe7A+r7lws58B7r+fgnQDK90cV45AXuvGx6i5CCSX1W/M3AJnHsNggDANBxEtWdNdFWcDd5LorB+RdSIlBw=="
+    },
+    "@ant-design/icons": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-4.2.1.tgz",
+      "integrity": "sha512-245ZI40MOr5GGws+sNSiJIRRoEf/J2xvPSMgwRYf3bv8mVGQZ6XTQI/OMeV16KtiSZ3D+mBKXVYSBz2fhigOXQ==",
+      "requires": {
+        "@ant-design/colors": "^3.1.0",
+        "@ant-design/icons-svg": "^4.0.0",
+        "@babel/runtime": "^7.10.1",
+        "classnames": "^2.2.6",
+        "insert-css": "^2.0.0",
+        "rc-util": "^5.0.1"
+      }
+    },
+    "@ant-design/icons-svg": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.1.0.tgz",
+      "integrity": "sha512-Fi03PfuUqRs76aI3UWYpP864lkrfPo0hluwGqh7NJdLhvH4iRDc3jbJqZIvRDLHKbXrvAfPPV3+zjUccfFvWOQ=="
+    },
+    "@ant-design/pro-layout": {
+      "version": "5.0.15",
+      "resolved": "https://registry.npmjs.org/@ant-design/pro-layout/-/pro-layout-5.0.15.tgz",
+      "integrity": "sha512-Q8D1H4SJmN+gF7coE58PNulfIJru1yhUXb6Zux6dO61+eFS+BWP3An2327VUbRlsUdGhSfToQoOX54SOVF10Yg==",
+      "requires": {
+        "@ant-design/icons": "^4.0.0",
+        "@umijs/route-utils": "^1.0.5",
+        "classnames": "^2.2.6",
+        "hash.js": "^1.1.7",
+        "history": "^4.10.1",
+        "lodash.isequal": "^4.5.0",
+        "memoize-one": "^5.1.1",
+        "omit.js": "^1.0.0",
+        "path-to-regexp": "2.4.0",
+        "qs": "^6.9.0",
+        "rc-resize-observer": "^0.2.1",
+        "react-copy-to-clipboard": "^5.0.1",
+        "react-responsive": "^8.0.1",
+        "react-router-dom": "5.1.2",
+        "unstated-next": "^1.1.0",
+        "use-json-comparison": "^1.0.3",
+        "use-media-antd-query": "^1.0.1",
+        "use-merge-value": "^1.0.1",
+        "warning": "^4.0.3"
+      },
+      "dependencies": {
+        "react-router-dom": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.1.2.tgz",
+          "integrity": "sha512-7BPHAaIwWpZS074UKaw1FjVdZBSVWEk8IuDXdB+OkLb8vd/WRQIpA4ag9WQk61aEfQs47wHyjWUoUGGZxpQXew==",
+          "requires": {
+            "@babel/runtime": "^7.1.2",
+            "history": "^4.9.0",
+            "loose-envify": "^1.3.1",
+            "prop-types": "^15.6.2",
+            "react-router": "5.1.2",
+            "tiny-invariant": "^1.0.2",
+            "tiny-warning": "^1.0.0"
+          }
+        }
+      }
+    },
+    "@ant-design/react-slick": {
+      "version": "0.26.1",
+      "resolved": "https://registry.npmjs.org/@ant-design/react-slick/-/react-slick-0.26.1.tgz",
+      "integrity": "sha512-1CR3vNFxAMmMb9btF6w9yT1xlrhZr6f/K+OkqoCLfWxN7h7jC16UCr1RsGBoFUdSq8bYfTr3pe6AiiCEDsALvA==",
+      "requires": {
+        "classnames": "^2.2.5",
+        "json2mq": "^0.2.0",
+        "lodash": "^4.17.15",
+        "resize-observer-polyfill": "^1.5.0"
+      }
+    },
+    "@babel/code-frame": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz",
+      "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==",
+      "dev": true,
+      "requires": {
+        "@babel/highlight": "^7.10.1"
+      }
+    },
+    "@babel/compat-data": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.10.1.tgz",
+      "integrity": "sha512-CHvCj7So7iCkGKPRFUfryXIkU2gSBw7VSZFYLsqVhrS47269VK2Hfi9S/YcublPMW8k1u2bQBlbDruoQEm4fgw==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.12.0",
+        "invariant": "^2.2.4",
+        "semver": "^5.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/core": {
+      "version": "7.8.4",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.4.tgz",
+      "integrity": "sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.8.3",
+        "@babel/generator": "^7.8.4",
+        "@babel/helpers": "^7.8.4",
+        "@babel/parser": "^7.8.4",
+        "@babel/template": "^7.8.3",
+        "@babel/traverse": "^7.8.4",
+        "@babel/types": "^7.8.3",
+        "convert-source-map": "^1.7.0",
+        "debug": "^4.1.0",
+        "gensync": "^1.0.0-beta.1",
+        "json5": "^2.1.0",
+        "lodash": "^4.17.13",
+        "resolve": "^1.3.2",
+        "semver": "^5.4.1",
+        "source-map": "^0.5.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "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"
+          }
+        },
+        "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
+        },
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+          "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
+        }
+      }
+    },
+    "@babel/generator": {
+      "version": "7.10.2",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz",
+      "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.10.2",
+        "jsesc": "^2.5.1",
+        "lodash": "^4.17.13",
+        "source-map": "^0.5.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+          "dev": true
+        }
+      }
+    },
+    "@babel/helper-annotate-as-pure": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz",
+      "integrity": "sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.10.1"
+      }
+    },
+    "@babel/helper-builder-binary-assignment-operator-visitor": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.1.tgz",
+      "integrity": "sha512-cQpVq48EkYxUU0xozpGCLla3wlkdRRqLWu1ksFMXA9CM5KQmyyRpSEsYXbao7JUkOw/tAaYKCaYyZq6HOFYtyw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-explode-assignable-expression": "^7.10.1",
+        "@babel/types": "^7.10.1"
+      }
+    },
+    "@babel/helper-builder-react-jsx": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.1.tgz",
+      "integrity": "sha512-KXzzpyWhXgzjXIlJU1ZjIXzUPdej1suE6vzqgImZ/cpAsR/CC8gUcX4EWRmDfWz/cs6HOCPMBIJ3nKoXt3BFuw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.10.1",
+        "@babel/types": "^7.10.1"
+      }
+    },
+    "@babel/helper-builder-react-jsx-experimental": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.10.1.tgz",
+      "integrity": "sha512-irQJ8kpQUV3JasXPSFQ+LCCtJSc5ceZrPFVj6TElR6XCHssi3jV8ch3odIrNtjJFRZZVbrOEfJMI79TPU/h1pQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.10.1",
+        "@babel/helper-module-imports": "^7.10.1",
+        "@babel/types": "^7.10.1"
+      }
+    },
+    "@babel/helper-compilation-targets": {
+      "version": "7.10.2",
+      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.2.tgz",
+      "integrity": "sha512-hYgOhF4To2UTB4LTaZepN/4Pl9LD4gfbJx8A34mqoluT8TLbof1mhUlYuNWTEebONa8+UlCC4X0TEXu7AOUyGA==",
+      "dev": true,
+      "requires": {
+        "@babel/compat-data": "^7.10.1",
+        "browserslist": "^4.12.0",
+        "invariant": "^2.2.4",
+        "levenary": "^1.1.1",
+        "semver": "^5.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/helper-create-class-features-plugin": {
+      "version": "7.10.2",
+      "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.2.tgz",
+      "integrity": "sha512-5C/QhkGFh1vqcziq1vAL6SI9ymzUp8BCYjFpvYVhWP4DlATIb3u5q3iUd35mvlyGs8fO7hckkW7i0tmH+5+bvQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "^7.10.1",
+        "@babel/helper-member-expression-to-functions": "^7.10.1",
+        "@babel/helper-optimise-call-expression": "^7.10.1",
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "@babel/helper-replace-supers": "^7.10.1",
+        "@babel/helper-split-export-declaration": "^7.10.1"
+      }
+    },
+    "@babel/helper-create-regexp-features-plugin": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.1.tgz",
+      "integrity": "sha512-Rx4rHS0pVuJn5pJOqaqcZR4XSgeF9G/pO/79t+4r7380tXFJdzImFnxMU19f83wjSrmKHq6myrM10pFHTGzkUA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.10.1",
+        "@babel/helper-regex": "^7.10.1",
+        "regexpu-core": "^4.7.0"
+      }
+    },
+    "@babel/helper-define-map": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.1.tgz",
+      "integrity": "sha512-+5odWpX+OnvkD0Zmq7panrMuAGQBu6aPUgvMzuMGo4R+jUOvealEj2hiqI6WhxgKrTpFoFj0+VdsuA8KDxHBDg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "^7.10.1",
+        "@babel/types": "^7.10.1",
+        "lodash": "^4.17.13"
+      }
+    },
+    "@babel/helper-explode-assignable-expression": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.1.tgz",
+      "integrity": "sha512-vcUJ3cDjLjvkKzt6rHrl767FeE7pMEYfPanq5L16GRtrXIoznc0HykNW2aEYkcnP76P0isoqJ34dDMFZwzEpJg==",
+      "dev": true,
+      "requires": {
+        "@babel/traverse": "^7.10.1",
+        "@babel/types": "^7.10.1"
+      }
+    },
+    "@babel/helper-function-name": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz",
+      "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-get-function-arity": "^7.10.1",
+        "@babel/template": "^7.10.1",
+        "@babel/types": "^7.10.1"
+      }
+    },
+    "@babel/helper-get-function-arity": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz",
+      "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.10.1"
+      }
+    },
+    "@babel/helper-hoist-variables": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.1.tgz",
+      "integrity": "sha512-vLm5srkU8rI6X3+aQ1rQJyfjvCBLXP8cAGeuw04zeAM2ItKb1e7pmVmLyHb4sDaAYnLL13RHOZPLEtcGZ5xvjg==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.10.1"
+      }
+    },
+    "@babel/helper-member-expression-to-functions": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz",
+      "integrity": "sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.10.1"
+      }
+    },
+    "@babel/helper-module-imports": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz",
+      "integrity": "sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.10.1"
+      }
+    },
+    "@babel/helper-module-transforms": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz",
+      "integrity": "sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.10.1",
+        "@babel/helper-replace-supers": "^7.10.1",
+        "@babel/helper-simple-access": "^7.10.1",
+        "@babel/helper-split-export-declaration": "^7.10.1",
+        "@babel/template": "^7.10.1",
+        "@babel/types": "^7.10.1",
+        "lodash": "^4.17.13"
+      }
+    },
+    "@babel/helper-optimise-call-expression": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz",
+      "integrity": "sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.10.1"
+      }
+    },
+    "@babel/helper-plugin-utils": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz",
+      "integrity": "sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==",
+      "dev": true
+    },
+    "@babel/helper-regex": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.1.tgz",
+      "integrity": "sha512-7isHr19RsIJWWLLFn21ubFt223PjQyg1HY7CZEMRr820HttHPpVvrsIN3bUOo44DEfFV4kBXO7Abbn9KTUZV7g==",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.17.13"
+      }
+    },
+    "@babel/helper-remap-async-to-generator": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.1.tgz",
+      "integrity": "sha512-RfX1P8HqsfgmJ6CwaXGKMAqbYdlleqglvVtht0HGPMSsy2V6MqLlOJVF/0Qyb/m2ZCi2z3q3+s6Pv7R/dQuZ6A==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.10.1",
+        "@babel/helper-wrap-function": "^7.10.1",
+        "@babel/template": "^7.10.1",
+        "@babel/traverse": "^7.10.1",
+        "@babel/types": "^7.10.1"
+      }
+    },
+    "@babel/helper-replace-supers": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz",
+      "integrity": "sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-member-expression-to-functions": "^7.10.1",
+        "@babel/helper-optimise-call-expression": "^7.10.1",
+        "@babel/traverse": "^7.10.1",
+        "@babel/types": "^7.10.1"
+      }
+    },
+    "@babel/helper-simple-access": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz",
+      "integrity": "sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw==",
+      "dev": true,
+      "requires": {
+        "@babel/template": "^7.10.1",
+        "@babel/types": "^7.10.1"
+      }
+    },
+    "@babel/helper-split-export-declaration": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz",
+      "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.10.1"
+      }
+    },
+    "@babel/helper-validator-identifier": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz",
+      "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==",
+      "dev": true
+    },
+    "@babel/helper-wrap-function": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.1.tgz",
+      "integrity": "sha512-C0MzRGteVDn+H32/ZgbAv5r56f2o1fZSA/rj/TYo8JEJNHg+9BdSmKBUND0shxWRztWhjlT2cvHYuynpPsVJwQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "^7.10.1",
+        "@babel/template": "^7.10.1",
+        "@babel/traverse": "^7.10.1",
+        "@babel/types": "^7.10.1"
+      }
+    },
+    "@babel/helpers": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.1.tgz",
+      "integrity": "sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw==",
+      "dev": true,
+      "requires": {
+        "@babel/template": "^7.10.1",
+        "@babel/traverse": "^7.10.1",
+        "@babel/types": "^7.10.1"
+      }
+    },
+    "@babel/highlight": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz",
+      "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-validator-identifier": "^7.10.1",
+        "chalk": "^2.0.0",
+        "js-tokens": "^4.0.0"
+      }
+    },
+    "@babel/parser": {
+      "version": "7.10.2",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz",
+      "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==",
+      "dev": true
+    },
+    "@babel/plugin-proposal-async-generator-functions": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.1.tgz",
+      "integrity": "sha512-vzZE12ZTdB336POZjmpblWfNNRpMSua45EYnRigE2XsZxcXcIyly2ixnTJasJE4Zq3U7t2d8rRF7XRUuzHxbOw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "@babel/helper-remap-async-to-generator": "^7.10.1",
+        "@babel/plugin-syntax-async-generators": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-class-properties": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.1.tgz",
+      "integrity": "sha512-sqdGWgoXlnOdgMXU+9MbhzwFRgxVLeiGBqTrnuS7LC2IBU31wSsESbTUreT2O418obpfPdGUR2GbEufZF1bpqw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-class-features-plugin": "^7.10.1",
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-proposal-decorators": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.8.3.tgz",
+      "integrity": "sha512-e3RvdvS4qPJVTe288DlXjwKflpfy1hr0j5dz5WpIYYeP7vQZg2WfAEIp8k5/Lwis/m5REXEteIz6rrcDtXXG7w==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-class-features-plugin": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/plugin-syntax-decorators": "^7.8.3"
+      }
+    },
+    "@babel/plugin-proposal-dynamic-import": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.1.tgz",
+      "integrity": "sha512-Cpc2yUVHTEGPlmiQzXj026kqwjEQAD9I4ZC16uzdbgWgitg/UHKHLffKNCQZ5+y8jpIZPJcKcwsr2HwPh+w3XA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "@babel/plugin-syntax-dynamic-import": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-json-strings": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.1.tgz",
+      "integrity": "sha512-m8r5BmV+ZLpWPtMY2mOKN7wre6HIO4gfIiV+eOmsnZABNenrt/kzYBwrh+KOfgumSWpnlGs5F70J8afYMSJMBg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "@babel/plugin-syntax-json-strings": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-nullish-coalescing-operator": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.1.tgz",
+      "integrity": "sha512-56cI/uHYgL2C8HVuHOuvVowihhX0sxb3nnfVRzUeVHTWmRHTZrKuAh/OBIMggGU/S1g/1D2CRCXqP+3u7vX7iA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-numeric-separator": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.1.tgz",
+      "integrity": "sha512-jjfym4N9HtCiNfyyLAVD8WqPYeHUrw4ihxuAynWj6zzp2gf9Ey2f7ImhFm6ikB3CLf5Z/zmcJDri6B4+9j9RsA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "@babel/plugin-syntax-numeric-separator": "^7.10.1"
+      }
+    },
+    "@babel/plugin-proposal-object-rest-spread": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.1.tgz",
+      "integrity": "sha512-Z+Qri55KiQkHh7Fc4BW6o+QBuTagbOp9txE+4U1i79u9oWlf2npkiDx+Rf3iK3lbcHBuNy9UOkwuR5wOMH3LIQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+        "@babel/plugin-transform-parameters": "^7.10.1"
+      }
+    },
+    "@babel/plugin-proposal-optional-catch-binding": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.1.tgz",
+      "integrity": "sha512-VqExgeE62YBqI3ogkGoOJp1R6u12DFZjqwJhqtKc2o5m1YTUuUWnos7bZQFBhwkxIFpWYJ7uB75U7VAPPiKETA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "@babel/plugin-syntax-optional-catch-binding": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-optional-chaining": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.1.tgz",
+      "integrity": "sha512-dqQj475q8+/avvok72CF3AOSV/SGEcH29zT5hhohqqvvZ2+boQoOr7iGldBG5YXTO2qgCgc2B3WvVLUdbeMlGA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "@babel/plugin-syntax-optional-chaining": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-private-methods": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.1.tgz",
+      "integrity": "sha512-RZecFFJjDiQ2z6maFprLgrdnm0OzoC23Mx89xf1CcEsxmHuzuXOdniEuI+S3v7vjQG4F5sa6YtUp+19sZuSxHg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-class-features-plugin": "^7.10.1",
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-proposal-unicode-property-regex": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.1.tgz",
+      "integrity": "sha512-JjfngYRvwmPwmnbRZyNiPFI8zxCZb8euzbCG/LxyKdeTb59tVciKo9GK9bi6JYKInk1H11Dq9j/zRqIH4KigfQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-regexp-features-plugin": "^7.10.1",
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@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.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.1.tgz",
+      "integrity": "sha512-Gf2Yx/iRs1JREDtVZ56OrjjgFHCaldpTnuy9BHla10qyVT3YkIIGEtoDWhyop0ksu1GvNjHIoYRBqm3zoR1jyQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-syntax-decorators": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.10.1.tgz",
+      "integrity": "sha512-a9OAbQhKOwSle1Vr0NJu/ISg1sPfdEkfRKWpgPuzhnWWzForou2gIeUIIwjAMHRekhhpJ7eulZlYs0H14Cbi+g==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@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-flow": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.10.1.tgz",
+      "integrity": "sha512-b3pWVncLBYoPP60UOTc7NMlbtsHQ6ITim78KQejNHK6WJ2mzV5kCcg4mIWpasAfJEgwVTibwo2e+FU7UEIKQUg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-syntax-json-strings": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+      "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-jsx": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.1.tgz",
+      "integrity": "sha512-+OxyOArpVFXQeXKLO9o+r2I4dIoVoy6+Uu0vKELrlweDM3QJADZj+Z+5ERansZqIZBcLj42vHnDI8Rz9BnRIuQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@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.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.1.tgz",
+      "integrity": "sha512-uTd0OsHrpe3tH5gRPTxG8Voh99/WCU78vIm5NMRYPAqC8lR4vajt6KkCAknCHrx24vkPdd/05yfdGSB4EIY2mg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@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.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.1.tgz",
+      "integrity": "sha512-hgA5RYkmZm8FTFT3yu2N9Bx7yVVOKYT6yEdXXo6j2JTm0wNxgqaGeQVaSHRjhfnQbX91DtjFB6McRFSlcJH3xQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-syntax-typescript": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.10.1.tgz",
+      "integrity": "sha512-X/d8glkrAtra7CaQGMiGs/OGa6XgUzqPcBXCIGFCpCqnfGlT0Wfbzo/B89xHhnInTaItPK8LALblVXcUOEh95Q==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-arrow-functions": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.1.tgz",
+      "integrity": "sha512-6AZHgFJKP3DJX0eCNJj01RpytUa3SOGawIxweHkNX2L6PYikOZmoh5B0d7hIHaIgveMjX990IAa/xK7jRTN8OA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-async-to-generator": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.1.tgz",
+      "integrity": "sha512-XCgYjJ8TY2slj6SReBUyamJn3k2JLUIiiR5b6t1mNCMSvv7yx+jJpaewakikp0uWFQSF7ChPPoe3dHmXLpISkg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.10.1",
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "@babel/helper-remap-async-to-generator": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-block-scoped-functions": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.1.tgz",
+      "integrity": "sha512-B7K15Xp8lv0sOJrdVAoukKlxP9N59HS48V1J3U/JGj+Ad+MHq+am6xJVs85AgXrQn4LV8vaYFOB+pr/yIuzW8Q==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-block-scoping": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.1.tgz",
+      "integrity": "sha512-8bpWG6TtF5akdhIm/uWTyjHqENpy13Fx8chg7pFH875aNLwX8JxIxqm08gmAT+Whe6AOmaTeLPe7dpLbXt+xUw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "lodash": "^4.17.13"
+      }
+    },
+    "@babel/plugin-transform-classes": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.1.tgz",
+      "integrity": "sha512-P9V0YIh+ln/B3RStPoXpEQ/CoAxQIhRSUn7aXqQ+FZJ2u8+oCtjIXR3+X0vsSD8zv+mb56K7wZW1XiDTDGiDRQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.10.1",
+        "@babel/helper-define-map": "^7.10.1",
+        "@babel/helper-function-name": "^7.10.1",
+        "@babel/helper-optimise-call-expression": "^7.10.1",
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "@babel/helper-replace-supers": "^7.10.1",
+        "@babel/helper-split-export-declaration": "^7.10.1",
+        "globals": "^11.1.0"
+      },
+      "dependencies": {
+        "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
+        }
+      }
+    },
+    "@babel/plugin-transform-computed-properties": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.1.tgz",
+      "integrity": "sha512-mqSrGjp3IefMsXIenBfGcPXxJxweQe2hEIwMQvjtiDQ9b1IBvDUjkAtV/HMXX47/vXf14qDNedXsIiNd1FmkaQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-destructuring": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.1.tgz",
+      "integrity": "sha512-V/nUc4yGWG71OhaTH705pU8ZSdM6c1KmmLP8ys59oOYbT7RpMYAR3MsVOt6OHL0WzG7BlTU076va9fjJyYzJMA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-dotall-regex": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.1.tgz",
+      "integrity": "sha512-19VIMsD1dp02RvduFUmfzj8uknaO3uiHHF0s3E1OHnVsNj8oge8EQ5RzHRbJjGSetRnkEuBYO7TG1M5kKjGLOA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-regexp-features-plugin": "^7.10.1",
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-duplicate-keys": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.1.tgz",
+      "integrity": "sha512-wIEpkX4QvX8Mo9W6XF3EdGttrIPZWozHfEaDTU0WJD/TDnXMvdDh30mzUl/9qWhnf7naicYartcEfUghTCSNpA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-exponentiation-operator": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.1.tgz",
+      "integrity": "sha512-lr/przdAbpEA2BUzRvjXdEDLrArGRRPwbaF9rvayuHRvdQ7lUTTkZnhZrJ4LE2jvgMRFF4f0YuPQ20vhiPYxtA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.1",
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-flow-strip-types": {
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.9.0.tgz",
+      "integrity": "sha512-7Qfg0lKQhEHs93FChxVLAvhBshOPQDtJUTVHr/ZwQNRccCm4O9D79r9tVSoV8iNwjP1YgfD+e/fgHcPkN1qEQg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/plugin-syntax-flow": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-for-of": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.1.tgz",
+      "integrity": "sha512-US8KCuxfQcn0LwSCMWMma8M2R5mAjJGsmoCBVwlMygvmDUMkTCykc84IqN1M7t+agSfOmLYTInLCHJM+RUoz+w==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-function-name": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.1.tgz",
+      "integrity": "sha512-//bsKsKFBJfGd65qSNNh1exBy5Y9gD9ZN+DvrJ8f7HXr4avE5POW6zB7Rj6VnqHV33+0vXWUwJT0wSHubiAQkw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "^7.10.1",
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-literals": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.1.tgz",
+      "integrity": "sha512-qi0+5qgevz1NHLZroObRm5A+8JJtibb7vdcPQF1KQE12+Y/xxl8coJ+TpPW9iRq+Mhw/NKLjm+5SHtAHCC7lAw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-member-expression-literals": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.1.tgz",
+      "integrity": "sha512-UmaWhDokOFT2GcgU6MkHC11i0NQcL63iqeufXWfRy6pUOGYeCGEKhvfFO6Vz70UfYJYHwveg62GS83Rvpxn+NA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-modules-amd": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.1.tgz",
+      "integrity": "sha512-31+hnWSFRI4/ACFr1qkboBbrTxoBIzj7qA69qlq8HY8p7+YCzkCT6/TvQ1a4B0z27VeWtAeJd6pr5G04dc1iHw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-transforms": "^7.10.1",
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "babel-plugin-dynamic-import-node": "^2.3.3"
+      }
+    },
+    "@babel/plugin-transform-modules-commonjs": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.1.tgz",
+      "integrity": "sha512-AQG4fc3KOah0vdITwt7Gi6hD9BtQP/8bhem7OjbaMoRNCH5Djx42O2vYMfau7QnAzQCa+RJnhJBmFFMGpQEzrg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-transforms": "^7.10.1",
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "@babel/helper-simple-access": "^7.10.1",
+        "babel-plugin-dynamic-import-node": "^2.3.3"
+      }
+    },
+    "@babel/plugin-transform-modules-systemjs": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.1.tgz",
+      "integrity": "sha512-ewNKcj1TQZDL3YnO85qh9zo1YF1CHgmSTlRQgHqe63oTrMI85cthKtZjAiZSsSNjPQ5NCaYo5QkbYqEw1ZBgZA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-hoist-variables": "^7.10.1",
+        "@babel/helper-module-transforms": "^7.10.1",
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "babel-plugin-dynamic-import-node": "^2.3.3"
+      }
+    },
+    "@babel/plugin-transform-modules-umd": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.1.tgz",
+      "integrity": "sha512-EIuiRNMd6GB6ulcYlETnYYfgv4AxqrswghmBRQbWLHZxN4s7mupxzglnHqk9ZiUpDI4eRWewedJJNj67PWOXKA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-transforms": "^7.10.1",
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-named-capturing-groups-regex": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz",
+      "integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-regexp-features-plugin": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-new-target": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.1.tgz",
+      "integrity": "sha512-MBlzPc1nJvbmO9rPr1fQwXOM2iGut+JC92ku6PbiJMMK7SnQc1rytgpopveE3Evn47gzvGYeCdgfCDbZo0ecUw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-object-super": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.1.tgz",
+      "integrity": "sha512-WnnStUDN5GL+wGQrJylrnnVlFhFmeArINIR9gjhSeYyvroGhBrSAXYg/RHsnfzmsa+onJrTJrEClPzgNmmQ4Gw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "@babel/helper-replace-supers": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-parameters": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.1.tgz",
+      "integrity": "sha512-tJ1T0n6g4dXMsL45YsSzzSDZCxiHXAQp/qHrucOq5gEHncTA3xDxnd5+sZcoQp+N1ZbieAaB8r/VUCG0gqseOg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-get-function-arity": "^7.10.1",
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-property-literals": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.1.tgz",
+      "integrity": "sha512-Kr6+mgag8auNrgEpbfIWzdXYOvqDHZOF0+Bx2xh4H2EDNwcbRb9lY6nkZg8oSjsX+DH9Ebxm9hOqtKW+gRDeNA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-react-constant-elements": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.10.1.tgz",
+      "integrity": "sha512-V4os6bkWt/jbrzfyVcZn2ZpuHZkvj3vyBU0U/dtS8SZuMS7Rfx5oknTrtfyXJ2/QZk8gX7Yls5Z921ItNpE30Q==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-react-display-name": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.10.1.tgz",
+      "integrity": "sha512-rBjKcVwjk26H3VX8pavMxGf33LNlbocMHdSeldIEswtQ/hrjyTG8fKKILW1cSkODyRovckN/uZlGb2+sAV9JUQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-react-jsx": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.1.tgz",
+      "integrity": "sha512-MBVworWiSRBap3Vs39eHt+6pJuLUAaK4oxGc8g+wY+vuSJvLiEQjW1LSTqKb8OUPtDvHCkdPhk7d6sjC19xyFw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-builder-react-jsx": "^7.10.1",
+        "@babel/helper-builder-react-jsx-experimental": "^7.10.1",
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "@babel/plugin-syntax-jsx": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-react-jsx-development": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.10.1.tgz",
+      "integrity": "sha512-XwDy/FFoCfw9wGFtdn5Z+dHh6HXKHkC6DwKNWpN74VWinUagZfDcEJc3Y8Dn5B3WMVnAllX8Kviaw7MtC5Epwg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-builder-react-jsx-experimental": "^7.10.1",
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "@babel/plugin-syntax-jsx": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-react-jsx-self": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.10.1.tgz",
+      "integrity": "sha512-4p+RBw9d1qV4S749J42ZooeQaBomFPrSxa9JONLHJ1TxCBo3TzJ79vtmG2S2erUT8PDDrPdw4ZbXGr2/1+dILA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "@babel/plugin-syntax-jsx": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-react-jsx-source": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.10.1.tgz",
+      "integrity": "sha512-neAbaKkoiL+LXYbGDvh6PjPG+YeA67OsZlE78u50xbWh2L1/C81uHiNP5d1fw+uqUIoiNdCC8ZB+G4Zh3hShJA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "@babel/plugin-syntax-jsx": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-react-pure-annotations": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.10.1.tgz",
+      "integrity": "sha512-mfhoiai083AkeewsBHUpaS/FM1dmUENHBMpS/tugSJ7VXqXO5dCN1Gkint2YvM1Cdv1uhmAKt1ZOuAjceKmlLA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.10.1",
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-regenerator": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.1.tgz",
+      "integrity": "sha512-B3+Y2prScgJ2Bh/2l9LJxKbb8C8kRfsG4AdPT+n7ixBHIxJaIG8bi8tgjxUMege1+WqSJ+7gu1YeoMVO3gPWzw==",
+      "dev": true,
+      "requires": {
+        "regenerator-transform": "^0.14.2"
+      }
+    },
+    "@babel/plugin-transform-reserved-words": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.1.tgz",
+      "integrity": "sha512-qN1OMoE2nuqSPmpTqEM7OvJ1FkMEV+BjVeZZm9V9mq/x1JLKQ4pcv8riZJMNN3u2AUGl0ouOMjRr2siecvHqUQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-runtime": {
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.9.0.tgz",
+      "integrity": "sha512-pUu9VSf3kI1OqbWINQ7MaugnitRss1z533436waNXp+0N3ur3zfut37sXiQMxkuCF4VUjwZucen/quskCh7NHw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "resolve": "^1.8.1",
+        "semver": "^5.5.1"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+          "dev": true
+        }
+      }
+    },
+    "@babel/plugin-transform-shorthand-properties": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.1.tgz",
+      "integrity": "sha512-AR0E/lZMfLstScFwztApGeyTHJ5u3JUKMjneqRItWeEqDdHWZwAOKycvQNCasCK/3r5YXsuNG25funcJDu7Y2g==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-spread": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.10.1.tgz",
+      "integrity": "sha512-8wTPym6edIrClW8FI2IoaePB91ETOtg36dOkj3bYcNe7aDMN2FXEoUa+WrmPc4xa1u2PQK46fUX2aCb+zo9rfw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-sticky-regex": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.1.tgz",
+      "integrity": "sha512-j17ojftKjrL7ufX8ajKvwRilwqTok4q+BjkknmQw9VNHnItTyMP5anPFzxFJdCQs7clLcWpCV3ma+6qZWLnGMA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "@babel/helper-regex": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-template-literals": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.1.tgz",
+      "integrity": "sha512-t7B/3MQf5M1T9hPCRG28DNGZUuxAuDqLYS03rJrIk2prj/UV7Z6FOneijhQhnv/Xa039vidXeVbvjK2SK5f7Gg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.10.1",
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-typeof-symbol": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.1.tgz",
+      "integrity": "sha512-qX8KZcmbvA23zDi+lk9s6hC1FM7jgLHYIjuLgULgc8QtYnmB3tAVIYkNoKRQ75qWBeyzcoMoK8ZQmogGtC/w0g==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-typescript": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.10.1.tgz",
+      "integrity": "sha512-v+QWKlmCnsaimLeqq9vyCsVRMViZG1k2SZTlcZvB+TqyH570Zsij8nvVUZzOASCRiQFUxkLrn9Wg/kH0zgy5OQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-class-features-plugin": "^7.10.1",
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "@babel/plugin-syntax-typescript": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-unicode-escapes": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.1.tgz",
+      "integrity": "sha512-zZ0Poh/yy1d4jeDWpx/mNwbKJVwUYJX73q+gyh4bwtG0/iUlzdEu0sLMda8yuDFS6LBQlT/ST1SJAR6zYwXWgw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/plugin-transform-unicode-regex": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.1.tgz",
+      "integrity": "sha512-Y/2a2W299k0VIUdbqYm9X2qS6fE0CUBhhiPpimK6byy7OJ/kORLlIX+J6UrjgNu5awvs62k+6RSslxhcvVw2Tw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-regexp-features-plugin": "^7.10.1",
+        "@babel/helper-plugin-utils": "^7.10.1"
+      }
+    },
+    "@babel/preset-env": {
+      "version": "7.10.2",
+      "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.10.2.tgz",
+      "integrity": "sha512-MjqhX0RZaEgK/KueRzh+3yPSk30oqDKJ5HP5tqTSB1e2gzGS3PLy7K0BIpnp78+0anFuSwOeuCf1zZO7RzRvEA==",
+      "dev": true,
+      "requires": {
+        "@babel/compat-data": "^7.10.1",
+        "@babel/helper-compilation-targets": "^7.10.2",
+        "@babel/helper-module-imports": "^7.10.1",
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "@babel/plugin-proposal-async-generator-functions": "^7.10.1",
+        "@babel/plugin-proposal-class-properties": "^7.10.1",
+        "@babel/plugin-proposal-dynamic-import": "^7.10.1",
+        "@babel/plugin-proposal-json-strings": "^7.10.1",
+        "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.1",
+        "@babel/plugin-proposal-numeric-separator": "^7.10.1",
+        "@babel/plugin-proposal-object-rest-spread": "^7.10.1",
+        "@babel/plugin-proposal-optional-catch-binding": "^7.10.1",
+        "@babel/plugin-proposal-optional-chaining": "^7.10.1",
+        "@babel/plugin-proposal-private-methods": "^7.10.1",
+        "@babel/plugin-proposal-unicode-property-regex": "^7.10.1",
+        "@babel/plugin-syntax-async-generators": "^7.8.0",
+        "@babel/plugin-syntax-class-properties": "^7.10.1",
+        "@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.1",
+        "@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.1",
+        "@babel/plugin-transform-arrow-functions": "^7.10.1",
+        "@babel/plugin-transform-async-to-generator": "^7.10.1",
+        "@babel/plugin-transform-block-scoped-functions": "^7.10.1",
+        "@babel/plugin-transform-block-scoping": "^7.10.1",
+        "@babel/plugin-transform-classes": "^7.10.1",
+        "@babel/plugin-transform-computed-properties": "^7.10.1",
+        "@babel/plugin-transform-destructuring": "^7.10.1",
+        "@babel/plugin-transform-dotall-regex": "^7.10.1",
+        "@babel/plugin-transform-duplicate-keys": "^7.10.1",
+        "@babel/plugin-transform-exponentiation-operator": "^7.10.1",
+        "@babel/plugin-transform-for-of": "^7.10.1",
+        "@babel/plugin-transform-function-name": "^7.10.1",
+        "@babel/plugin-transform-literals": "^7.10.1",
+        "@babel/plugin-transform-member-expression-literals": "^7.10.1",
+        "@babel/plugin-transform-modules-amd": "^7.10.1",
+        "@babel/plugin-transform-modules-commonjs": "^7.10.1",
+        "@babel/plugin-transform-modules-systemjs": "^7.10.1",
+        "@babel/plugin-transform-modules-umd": "^7.10.1",
+        "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3",
+        "@babel/plugin-transform-new-target": "^7.10.1",
+        "@babel/plugin-transform-object-super": "^7.10.1",
+        "@babel/plugin-transform-parameters": "^7.10.1",
+        "@babel/plugin-transform-property-literals": "^7.10.1",
+        "@babel/plugin-transform-regenerator": "^7.10.1",
+        "@babel/plugin-transform-reserved-words": "^7.10.1",
+        "@babel/plugin-transform-shorthand-properties": "^7.10.1",
+        "@babel/plugin-transform-spread": "^7.10.1",
+        "@babel/plugin-transform-sticky-regex": "^7.10.1",
+        "@babel/plugin-transform-template-literals": "^7.10.1",
+        "@babel/plugin-transform-typeof-symbol": "^7.10.1",
+        "@babel/plugin-transform-unicode-escapes": "^7.10.1",
+        "@babel/plugin-transform-unicode-regex": "^7.10.1",
+        "@babel/preset-modules": "^0.1.3",
+        "@babel/types": "^7.10.2",
+        "browserslist": "^4.12.0",
+        "core-js-compat": "^3.6.2",
+        "invariant": "^2.2.2",
+        "levenary": "^1.1.1",
+        "semver": "^5.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/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/preset-react": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.10.1.tgz",
+      "integrity": "sha512-Rw0SxQ7VKhObmFjD/cUcKhPTtzpeviEFX1E6PgP+cYOhQ98icNqtINNFANlsdbQHrmeWnqdxA4Tmnl1jy5tp3Q==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.1",
+        "@babel/plugin-transform-react-display-name": "^7.10.1",
+        "@babel/plugin-transform-react-jsx": "^7.10.1",
+        "@babel/plugin-transform-react-jsx-development": "^7.10.1",
+        "@babel/plugin-transform-react-jsx-self": "^7.10.1",
+        "@babel/plugin-transform-react-jsx-source": "^7.10.1",
+        "@babel/plugin-transform-react-pure-annotations": "^7.10.1"
+      }
+    },
+    "@babel/preset-typescript": {
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.9.0.tgz",
+      "integrity": "sha512-S4cueFnGrIbvYJgwsVFKdvOmpiL0XGw9MFW9D0vgRys5g36PBhZRL8NX8Gr2akz8XRtzq6HuDXPD/1nniagNUg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/plugin-transform-typescript": "^7.9.0"
+      }
+    },
+    "@babel/runtime": {
+      "version": "7.10.2",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.2.tgz",
+      "integrity": "sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg==",
+      "requires": {
+        "regenerator-runtime": "^0.13.4"
+      }
+    },
+    "@babel/runtime-corejs3": {
+      "version": "7.10.2",
+      "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.2.tgz",
+      "integrity": "sha512-+a2M/u7r15o3dV1NEizr9bRi+KUVnrs/qYxF0Z06DAPx/4VCWaz1WA7EcbE+uqGgt39lp5akWGmHsTseIkHkHg==",
+      "dev": true,
+      "requires": {
+        "core-js-pure": "^3.0.0",
+        "regenerator-runtime": "^0.13.4"
+      }
+    },
+    "@babel/template": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz",
+      "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.10.1",
+        "@babel/parser": "^7.10.1",
+        "@babel/types": "^7.10.1"
+      }
+    },
+    "@babel/traverse": {
+      "version": "7.10.1",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz",
+      "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.10.1",
+        "@babel/generator": "^7.10.1",
+        "@babel/helper-function-name": "^7.10.1",
+        "@babel/helper-split-export-declaration": "^7.10.1",
+        "@babel/parser": "^7.10.1",
+        "@babel/types": "^7.10.1",
+        "debug": "^4.1.0",
+        "globals": "^11.1.0",
+        "lodash": "^4.17.13"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "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
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        }
+      }
+    },
+    "@babel/types": {
+      "version": "7.10.2",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz",
+      "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-validator-identifier": "^7.10.1",
+        "lodash": "^4.17.13",
+        "to-fast-properties": "^2.0.0"
+      }
+    },
+    "@cnakazawa/watch": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz",
+      "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==",
+      "dev": true,
+      "requires": {
+        "exec-sh": "^0.3.2",
+        "minimist": "^1.2.0"
+      }
+    },
+    "@commitlint/cli": {
+      "version": "8.3.5",
+      "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-8.3.5.tgz",
+      "integrity": "sha512-6+L0vbw55UEdht71pgWOE55SRgb+8OHcEwGDB234VlIBFGK9P2QOBU7MHiYJ5cjdjCQ0rReNrGjOHmJ99jwf0w==",
+      "dev": true,
+      "requires": {
+        "@commitlint/format": "^8.3.4",
+        "@commitlint/lint": "^8.3.5",
+        "@commitlint/load": "^8.3.5",
+        "@commitlint/read": "^8.3.4",
+        "babel-polyfill": "6.26.0",
+        "chalk": "2.4.2",
+        "get-stdin": "7.0.0",
+        "lodash": "4.17.15",
+        "meow": "5.0.0",
+        "resolve-from": "5.0.0",
+        "resolve-global": "1.0.0"
+      }
+    },
+    "@commitlint/config-conventional": {
+      "version": "8.3.4",
+      "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-8.3.4.tgz",
+      "integrity": "sha512-w0Yc5+aVAjZgjYqx29igBOnVCj8O22gy3Vo6Fyp7PwoS7+AYS1x3sN7IBq6i7Ae15Mv5P+rEx1pkxXo5zOMe4g==",
+      "dev": true,
+      "requires": {
+        "conventional-changelog-conventionalcommits": "4.2.1"
+      }
+    },
+    "@commitlint/ensure": {
+      "version": "8.3.4",
+      "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-8.3.4.tgz",
+      "integrity": "sha512-8NW77VxviLhD16O3EUd02lApMFnrHexq10YS4F4NftNoErKbKaJ0YYedktk2boKrtNRf/gQHY/Qf65edPx4ipw==",
+      "dev": true,
+      "requires": {
+        "lodash": "4.17.15"
+      }
+    },
+    "@commitlint/execute-rule": {
+      "version": "8.3.4",
+      "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-8.3.4.tgz",
+      "integrity": "sha512-f4HigYjeIBn9f7OuNv5zh2y5vWaAhNFrfeul8CRJDy82l3Y+09lxOTGxfF3uMXKrZq4LmuK6qvvRCZ8mUrVvzQ==",
+      "dev": true
+    },
+    "@commitlint/format": {
+      "version": "8.3.4",
+      "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-8.3.4.tgz",
+      "integrity": "sha512-809wlQ/ND6CLZON+w2Rb3YM2TLNDfU2xyyqpZeqzf2reJNpySMSUAeaO/fNDJSOKIsOsR3bI01rGu6hv28k+Nw==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.0.1"
+      }
+    },
+    "@commitlint/is-ignored": {
+      "version": "8.3.5",
+      "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-8.3.5.tgz",
+      "integrity": "sha512-Zo+8a6gJLFDTqyNRx53wQi/XTiz8mncvmWf/4oRG+6WRcBfjSSHY7KPVj5Y6UaLy2EgZ0WQ2Tt6RdTDeQiQplA==",
+      "dev": true,
+      "requires": {
+        "semver": "6.3.0"
+      }
+    },
+    "@commitlint/lint": {
+      "version": "8.3.5",
+      "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-8.3.5.tgz",
+      "integrity": "sha512-02AkI0a6PU6rzqUvuDkSi6rDQ2hUgkq9GpmdJqfai5bDbxx2939mK4ZO+7apbIh4H6Pae7EpYi7ffxuJgm+3hQ==",
+      "dev": true,
+      "requires": {
+        "@commitlint/is-ignored": "^8.3.5",
+        "@commitlint/parse": "^8.3.4",
+        "@commitlint/rules": "^8.3.4",
+        "babel-runtime": "^6.23.0",
+        "lodash": "4.17.15"
+      }
+    },
+    "@commitlint/load": {
+      "version": "8.3.5",
+      "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-8.3.5.tgz",
+      "integrity": "sha512-poF7R1CtQvIXRmVIe63FjSQmN9KDqjRtU5A6hxqXBga87yB2VUJzic85TV6PcQc+wStk52cjrMI+g0zFx+Zxrw==",
+      "dev": true,
+      "requires": {
+        "@commitlint/execute-rule": "^8.3.4",
+        "@commitlint/resolve-extends": "^8.3.5",
+        "babel-runtime": "^6.23.0",
+        "chalk": "2.4.2",
+        "cosmiconfig": "^5.2.0",
+        "lodash": "4.17.15",
+        "resolve-from": "^5.0.0"
+      }
+    },
+    "@commitlint/message": {
+      "version": "8.3.4",
+      "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-8.3.4.tgz",
+      "integrity": "sha512-nEj5tknoOKXqBsaQtCtgPcsAaf5VCg3+fWhss4Vmtq40633xLq0irkdDdMEsYIx8rGR0XPBTukqzln9kAWCkcA==",
+      "dev": true
+    },
+    "@commitlint/parse": {
+      "version": "8.3.4",
+      "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-8.3.4.tgz",
+      "integrity": "sha512-b3uQvpUQWC20EBfKSfMRnyx5Wc4Cn778bVeVOFErF/cXQK725L1bYFvPnEjQO/GT8yGVzq2wtLaoEqjm1NJ/Bw==",
+      "dev": true,
+      "requires": {
+        "conventional-changelog-angular": "^1.3.3",
+        "conventional-commits-parser": "^3.0.0",
+        "lodash": "^4.17.11"
+      }
+    },
+    "@commitlint/read": {
+      "version": "8.3.4",
+      "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-8.3.4.tgz",
+      "integrity": "sha512-FKv1kHPrvcAG5j+OSbd41IWexsbLhfIXpxVC/YwQZO+FR0EHmygxQNYs66r+GnhD1EfYJYM4WQIqd5bJRx6OIw==",
+      "dev": true,
+      "requires": {
+        "@commitlint/top-level": "^8.3.4",
+        "@marionebl/sander": "^0.6.0",
+        "babel-runtime": "^6.23.0",
+        "git-raw-commits": "^2.0.0"
+      }
+    },
+    "@commitlint/resolve-extends": {
+      "version": "8.3.5",
+      "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-8.3.5.tgz",
+      "integrity": "sha512-nHhFAK29qiXNe6oH6uG5wqBnCR+BQnxlBW/q5fjtxIaQALgfoNLHwLS9exzbIRFqwJckpR6yMCfgMbmbAOtklQ==",
+      "dev": true,
+      "requires": {
+        "import-fresh": "^3.0.0",
+        "lodash": "4.17.15",
+        "resolve-from": "^5.0.0",
+        "resolve-global": "^1.0.0"
+      }
+    },
+    "@commitlint/rules": {
+      "version": "8.3.4",
+      "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-8.3.4.tgz",
+      "integrity": "sha512-xuC9dlqD5xgAoDFgnbs578cJySvwOSkMLQyZADb1xD5n7BNcUJfP8WjT9W1Aw8K3Wf8+Ym/ysr9FZHXInLeaRg==",
+      "dev": true,
+      "requires": {
+        "@commitlint/ensure": "^8.3.4",
+        "@commitlint/message": "^8.3.4",
+        "@commitlint/to-lines": "^8.3.4",
+        "babel-runtime": "^6.23.0"
+      }
+    },
+    "@commitlint/to-lines": {
+      "version": "8.3.4",
+      "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-8.3.4.tgz",
+      "integrity": "sha512-5AvcdwRsMIVq0lrzXTwpbbG5fKRTWcHkhn/hCXJJ9pm1JidsnidS1y0RGkb3O50TEHGewhXwNoavxW9VToscUA==",
+      "dev": true
+    },
+    "@commitlint/top-level": {
+      "version": "8.3.4",
+      "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-8.3.4.tgz",
+      "integrity": "sha512-nOaeLBbAqSZNpKgEtO6NAxmui1G8ZvLG+0wb4rvv6mWhPDzK1GNZkCd8FUZPahCoJ1iHDoatw7F8BbJLg4nDjg==",
+      "dev": true,
+      "requires": {
+        "find-up": "^4.0.0"
+      }
+    },
+    "@csstools/convert-colors": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz",
+      "integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==",
+      "dev": true
+    },
+    "@csstools/normalize.css": {
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz",
+      "integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==",
+      "dev": true
+    },
+    "@hapi/address": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz",
+      "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==",
+      "dev": true
+    },
+    "@hapi/bourne": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz",
+      "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==",
+      "dev": true
+    },
+    "@hapi/hoek": {
+      "version": "8.5.1",
+      "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz",
+      "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==",
+      "dev": true
+    },
+    "@hapi/joi": {
+      "version": "15.1.1",
+      "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz",
+      "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==",
+      "dev": true,
+      "requires": {
+        "@hapi/address": "2.x.x",
+        "@hapi/bourne": "1.x.x",
+        "@hapi/hoek": "8.x.x",
+        "@hapi/topo": "3.x.x"
+      }
+    },
+    "@hapi/topo": {
+      "version": "3.1.6",
+      "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz",
+      "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==",
+      "dev": true,
+      "requires": {
+        "@hapi/hoek": "^8.3.0"
+      }
+    },
+    "@hot-loader/react-dom": {
+      "version": "16.13.0",
+      "resolved": "https://registry.npmjs.org/@hot-loader/react-dom/-/react-dom-16.13.0.tgz",
+      "integrity": "sha512-lJZrmkucz2MrQJTQtJobx5MICXcfQvKihszqv655p557HPi0hMOWxrNpiHv3DWD8ugNWjtWcVWqRnFvwsHq1mQ==",
+      "dev": true,
+      "requires": {
+        "loose-envify": "^1.1.0",
+        "object-assign": "^4.1.1",
+        "prop-types": "^15.6.2",
+        "scheduler": "^0.19.0"
+      }
+    },
+    "@jest/console": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz",
+      "integrity": "sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==",
+      "dev": true,
+      "requires": {
+        "@jest/source-map": "^24.9.0",
+        "chalk": "^2.0.1",
+        "slash": "^2.0.0"
+      },
+      "dependencies": {
+        "slash": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+          "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+          "dev": true
+        }
+      }
+    },
+    "@jest/core": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.9.0.tgz",
+      "integrity": "sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A==",
+      "dev": true,
+      "requires": {
+        "@jest/console": "^24.7.1",
+        "@jest/reporters": "^24.9.0",
+        "@jest/test-result": "^24.9.0",
+        "@jest/transform": "^24.9.0",
+        "@jest/types": "^24.9.0",
+        "ansi-escapes": "^3.0.0",
+        "chalk": "^2.0.1",
+        "exit": "^0.1.2",
+        "graceful-fs": "^4.1.15",
+        "jest-changed-files": "^24.9.0",
+        "jest-config": "^24.9.0",
+        "jest-haste-map": "^24.9.0",
+        "jest-message-util": "^24.9.0",
+        "jest-regex-util": "^24.3.0",
+        "jest-resolve": "^24.9.0",
+        "jest-resolve-dependencies": "^24.9.0",
+        "jest-runner": "^24.9.0",
+        "jest-runtime": "^24.9.0",
+        "jest-snapshot": "^24.9.0",
+        "jest-util": "^24.9.0",
+        "jest-validate": "^24.9.0",
+        "jest-watcher": "^24.9.0",
+        "micromatch": "^3.1.10",
+        "p-each-series": "^1.0.0",
+        "realpath-native": "^1.1.0",
+        "rimraf": "^2.5.4",
+        "slash": "^2.0.0",
+        "strip-ansi": "^5.0.0"
+      },
+      "dependencies": {
+        "slash": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+          "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+          "dev": true
+        }
+      }
+    },
+    "@jest/environment": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.9.0.tgz",
+      "integrity": "sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ==",
+      "dev": true,
+      "requires": {
+        "@jest/fake-timers": "^24.9.0",
+        "@jest/transform": "^24.9.0",
+        "@jest/types": "^24.9.0",
+        "jest-mock": "^24.9.0"
+      }
+    },
+    "@jest/fake-timers": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.9.0.tgz",
+      "integrity": "sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^24.9.0",
+        "jest-message-util": "^24.9.0",
+        "jest-mock": "^24.9.0"
+      }
+    },
+    "@jest/reporters": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.9.0.tgz",
+      "integrity": "sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw==",
+      "dev": true,
+      "requires": {
+        "@jest/environment": "^24.9.0",
+        "@jest/test-result": "^24.9.0",
+        "@jest/transform": "^24.9.0",
+        "@jest/types": "^24.9.0",
+        "chalk": "^2.0.1",
+        "exit": "^0.1.2",
+        "glob": "^7.1.2",
+        "istanbul-lib-coverage": "^2.0.2",
+        "istanbul-lib-instrument": "^3.0.1",
+        "istanbul-lib-report": "^2.0.4",
+        "istanbul-lib-source-maps": "^3.0.1",
+        "istanbul-reports": "^2.2.6",
+        "jest-haste-map": "^24.9.0",
+        "jest-resolve": "^24.9.0",
+        "jest-runtime": "^24.9.0",
+        "jest-util": "^24.9.0",
+        "jest-worker": "^24.6.0",
+        "node-notifier": "^5.4.2",
+        "slash": "^2.0.0",
+        "source-map": "^0.6.0",
+        "string-length": "^2.0.0"
+      },
+      "dependencies": {
+        "slash": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+          "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+          "dev": true
+        }
+      }
+    },
+    "@jest/source-map": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz",
+      "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==",
+      "dev": true,
+      "requires": {
+        "callsites": "^3.0.0",
+        "graceful-fs": "^4.1.15",
+        "source-map": "^0.6.0"
+      }
+    },
+    "@jest/test-result": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz",
+      "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==",
+      "dev": true,
+      "requires": {
+        "@jest/console": "^24.9.0",
+        "@jest/types": "^24.9.0",
+        "@types/istanbul-lib-coverage": "^2.0.0"
+      }
+    },
+    "@jest/test-sequencer": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz",
+      "integrity": "sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==",
+      "dev": true,
+      "requires": {
+        "@jest/test-result": "^24.9.0",
+        "jest-haste-map": "^24.9.0",
+        "jest-runner": "^24.9.0",
+        "jest-runtime": "^24.9.0"
+      }
+    },
+    "@jest/transform": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.9.0.tgz",
+      "integrity": "sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==",
+      "dev": true,
+      "requires": {
+        "@babel/core": "^7.1.0",
+        "@jest/types": "^24.9.0",
+        "babel-plugin-istanbul": "^5.1.0",
+        "chalk": "^2.0.1",
+        "convert-source-map": "^1.4.0",
+        "fast-json-stable-stringify": "^2.0.0",
+        "graceful-fs": "^4.1.15",
+        "jest-haste-map": "^24.9.0",
+        "jest-regex-util": "^24.9.0",
+        "jest-util": "^24.9.0",
+        "micromatch": "^3.1.10",
+        "pirates": "^4.0.1",
+        "realpath-native": "^1.1.0",
+        "slash": "^2.0.0",
+        "source-map": "^0.6.1",
+        "write-file-atomic": "2.4.1"
+      },
+      "dependencies": {
+        "slash": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+          "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+          "dev": true
+        }
+      }
+    },
+    "@jest/types": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz",
+      "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==",
+      "dev": true,
+      "requires": {
+        "@types/istanbul-lib-coverage": "^2.0.0",
+        "@types/istanbul-reports": "^1.1.1",
+        "@types/yargs": "^13.0.0"
+      }
+    },
+    "@marionebl/sander": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/@marionebl/sander/-/sander-0.6.1.tgz",
+      "integrity": "sha1-GViWWHTyS8Ub5Ih1/rUNZC/EH3s=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.3",
+        "mkdirp": "^0.5.1",
+        "rimraf": "^2.5.2"
+      }
+    },
+    "@mrmlnc/readdir-enhanced": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
+      "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==",
+      "dev": true,
+      "requires": {
+        "call-me-maybe": "^1.0.1",
+        "glob-to-regexp": "^0.3.0"
+      }
+    },
+    "@nodelib/fs.scandir": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
+      "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==",
+      "dev": true,
+      "requires": {
+        "@nodelib/fs.stat": "2.0.3",
+        "run-parallel": "^1.1.9"
+      },
+      "dependencies": {
+        "@nodelib/fs.stat": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz",
+          "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==",
+          "dev": true
+        }
+      }
+    },
+    "@nodelib/fs.stat": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
+      "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==",
+      "dev": true
+    },
+    "@nodelib/fs.walk": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz",
+      "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==",
+      "dev": true,
+      "requires": {
+        "@nodelib/fs.scandir": "2.1.3",
+        "fastq": "^1.6.0"
+      }
+    },
+    "@reactseed/devserver": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/@reactseed/devserver/-/devserver-0.0.2.tgz",
+      "integrity": "sha512-4dYOHgmi0ymTbi+XYZPDCnnEf7FYz3UPcJP3sVbneozR9/jKLFc2MaJF6lihaJXUT5JWUVn7b/2TVby89iGHzQ==",
+      "dev": true
+    },
+    "@reactseed/use-redux": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/@reactseed/use-redux/-/use-redux-0.0.3.tgz",
+      "integrity": "sha512-RFn+lxQET4eHSjULHOotZHBF52EtnVyUc8k2EXbuAGqE+1n6QSpgx5JSKAPBNM1fwa08CbA5fhDiA6EoyVqh5w=="
+    },
+    "@reactseed/use-request": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/@reactseed/use-request/-/use-request-0.0.2.tgz",
+      "integrity": "sha512-SzVRvkus5hr6TRIfvHCEC4RDBKPboPKwy5Yu4pWfdZ3K5xaeWSpEVsCTtnkQldMx4epNXl83NSFEjugS7R7Ung==",
+      "requires": {
+        "@umijs/use-request": "^1.4.2",
+        "axios": "^0.19.2"
+      }
+    },
+    "@sheerun/mutationobserver-shim": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz",
+      "integrity": "sha512-DetpxZw1fzPD5xUBrIAoplLChO2VB8DlL5Gg+I1IR9b2wPqYIca2WSUxL5g1vLeR4MsQq1NeWriXAVffV+U1Fw==",
+      "dev": true
+    },
+    "@stylelint/postcss-css-in-js": {
+      "version": "0.37.1",
+      "resolved": "https://registry.npmjs.org/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.1.tgz",
+      "integrity": "sha512-UMf2Rni3JGKi3ZwYRGMYJ5ipOA5ENJSKMtYA/pE1ZLURwdh7B5+z2r73RmWvub+N0UuH1Lo+TGfCgYwPvqpXNw==",
+      "dev": true,
+      "requires": {
+        "@babel/core": ">=7.9.0"
+      },
+      "dependencies": {
+        "@babel/core": {
+          "version": "7.10.2",
+          "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.2.tgz",
+          "integrity": "sha512-KQmV9yguEjQsXqyOUGKjS4+3K8/DlOCE2pZcq4augdQmtTy5iv5EHtmMSJ7V4c1BIPjuwtZYqYLCq9Ga+hGBRQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.10.1",
+            "@babel/generator": "^7.10.2",
+            "@babel/helper-module-transforms": "^7.10.1",
+            "@babel/helpers": "^7.10.1",
+            "@babel/parser": "^7.10.2",
+            "@babel/template": "^7.10.1",
+            "@babel/traverse": "^7.10.1",
+            "@babel/types": "^7.10.2",
+            "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"
+          }
+        },
+        "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"
+          }
+        },
+        "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"
+          }
+        },
+        "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
+        },
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+          "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
+        }
+      }
+    },
+    "@stylelint/postcss-markdown": {
+      "version": "0.36.1",
+      "resolved": "https://registry.npmjs.org/@stylelint/postcss-markdown/-/postcss-markdown-0.36.1.tgz",
+      "integrity": "sha512-iDxMBWk9nB2BPi1VFQ+Dc5+XpvODBHw2n3tYpaBZuEAFQlbtF9If0Qh5LTTwSi/XwdbJ2jt+0dis3i8omyggpw==",
+      "dev": true,
+      "requires": {
+        "remark": "^12.0.0",
+        "unist-util-find-all-after": "^3.0.1"
+      }
+    },
+    "@svgr/babel-plugin-add-jsx-attribute": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz",
+      "integrity": "sha512-j7KnilGyZzYr/jhcrSYS3FGWMZVaqyCG0vzMCwzvei0coIkczuYMcniK07nI0aHJINciujjH11T72ICW5eL5Ig==",
+      "dev": true
+    },
+    "@svgr/babel-plugin-remove-jsx-attribute": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-4.2.0.tgz",
+      "integrity": "sha512-3XHLtJ+HbRCH4n28S7y/yZoEQnRpl0tvTZQsHqvaeNXPra+6vE5tbRliH3ox1yZYPCxrlqaJT/Mg+75GpDKlvQ==",
+      "dev": true
+    },
+    "@svgr/babel-plugin-remove-jsx-empty-expression": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-4.2.0.tgz",
+      "integrity": "sha512-yTr2iLdf6oEuUE9MsRdvt0NmdpMBAkgK8Bjhl6epb+eQWk6abBaX3d65UZ3E3FWaOwePyUgNyNCMVG61gGCQ7w==",
+      "dev": true
+    },
+    "@svgr/babel-plugin-replace-jsx-attribute-value": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-4.2.0.tgz",
+      "integrity": "sha512-U9m870Kqm0ko8beHawRXLGLvSi/ZMrl89gJ5BNcT452fAjtF2p4uRzXkdzvGJJJYBgx7BmqlDjBN/eCp5AAX2w==",
+      "dev": true
+    },
+    "@svgr/babel-plugin-svg-dynamic-title": {
+      "version": "4.3.3",
+      "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-4.3.3.tgz",
+      "integrity": "sha512-w3Be6xUNdwgParsvxkkeZb545VhXEwjGMwExMVBIdPQJeyMQHqm9Msnb2a1teHBqUYL66qtwfhNkbj1iarCG7w==",
+      "dev": true
+    },
+    "@svgr/babel-plugin-svg-em-dimensions": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-4.2.0.tgz",
+      "integrity": "sha512-C0Uy+BHolCHGOZ8Dnr1zXy/KgpBOkEUYY9kI/HseHVPeMbluaX3CijJr7D4C5uR8zrc1T64nnq/k63ydQuGt4w==",
+      "dev": true
+    },
+    "@svgr/babel-plugin-transform-react-native-svg": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-4.2.0.tgz",
+      "integrity": "sha512-7YvynOpZDpCOUoIVlaaOUU87J4Z6RdD6spYN4eUb5tfPoKGSF9OG2NuhgYnq4jSkAxcpMaXWPf1cePkzmqTPNw==",
+      "dev": true
+    },
+    "@svgr/babel-plugin-transform-svg-component": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-4.2.0.tgz",
+      "integrity": "sha512-hYfYuZhQPCBVotABsXKSCfel2slf/yvJY8heTVX1PCTaq/IgASq1IyxPPKJ0chWREEKewIU/JMSsIGBtK1KKxw==",
+      "dev": true
+    },
+    "@svgr/babel-preset": {
+      "version": "4.3.3",
+      "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-4.3.3.tgz",
+      "integrity": "sha512-6PG80tdz4eAlYUN3g5GZiUjg2FMcp+Wn6rtnz5WJG9ITGEF1pmFdzq02597Hn0OmnQuCVaBYQE1OVFAnwOl+0A==",
+      "dev": true,
+      "requires": {
+        "@svgr/babel-plugin-add-jsx-attribute": "^4.2.0",
+        "@svgr/babel-plugin-remove-jsx-attribute": "^4.2.0",
+        "@svgr/babel-plugin-remove-jsx-empty-expression": "^4.2.0",
+        "@svgr/babel-plugin-replace-jsx-attribute-value": "^4.2.0",
+        "@svgr/babel-plugin-svg-dynamic-title": "^4.3.3",
+        "@svgr/babel-plugin-svg-em-dimensions": "^4.2.0",
+        "@svgr/babel-plugin-transform-react-native-svg": "^4.2.0",
+        "@svgr/babel-plugin-transform-svg-component": "^4.2.0"
+      }
+    },
+    "@svgr/core": {
+      "version": "4.3.3",
+      "resolved": "https://registry.npmjs.org/@svgr/core/-/core-4.3.3.tgz",
+      "integrity": "sha512-qNuGF1QON1626UCaZamWt5yedpgOytvLj5BQZe2j1k1B8DUG4OyugZyfEwBeXozCUwhLEpsrgPrE+eCu4fY17w==",
+      "dev": true,
+      "requires": {
+        "@svgr/plugin-jsx": "^4.3.3",
+        "camelcase": "^5.3.1",
+        "cosmiconfig": "^5.2.1"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "5.3.1",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+          "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+          "dev": true
+        }
+      }
+    },
+    "@svgr/hast-util-to-babel-ast": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-4.3.2.tgz",
+      "integrity": "sha512-JioXclZGhFIDL3ddn4Kiq8qEqYM2PyDKV0aYno8+IXTLuYt6TOgHUbUAAFvqtb0Xn37NwP0BTHglejFoYr8RZg==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.4.4"
+      }
+    },
+    "@svgr/plugin-jsx": {
+      "version": "4.3.3",
+      "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-4.3.3.tgz",
+      "integrity": "sha512-cLOCSpNWQnDB1/v+SUENHH7a0XY09bfuMKdq9+gYvtuwzC2rU4I0wKGFEp1i24holdQdwodCtDQdFtJiTCWc+w==",
+      "dev": true,
+      "requires": {
+        "@babel/core": "^7.4.5",
+        "@svgr/babel-preset": "^4.3.3",
+        "@svgr/hast-util-to-babel-ast": "^4.3.2",
+        "svg-parser": "^2.0.0"
+      }
+    },
+    "@svgr/plugin-svgo": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-4.3.1.tgz",
+      "integrity": "sha512-PrMtEDUWjX3Ea65JsVCwTIXuSqa3CG9px+DluF1/eo9mlDrgrtFE7NE/DjdhjJgSM9wenlVBzkzneSIUgfUI/w==",
+      "dev": true,
+      "requires": {
+        "cosmiconfig": "^5.2.1",
+        "merge-deep": "^3.0.2",
+        "svgo": "^1.2.2"
+      }
+    },
+    "@svgr/webpack": {
+      "version": "4.3.3",
+      "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-4.3.3.tgz",
+      "integrity": "sha512-bjnWolZ6KVsHhgyCoYRFmbd26p8XVbulCzSG53BDQqAr+JOAderYK7CuYrB3bDjHJuF6LJ7Wrr42+goLRV9qIg==",
+      "dev": true,
+      "requires": {
+        "@babel/core": "^7.4.5",
+        "@babel/plugin-transform-react-constant-elements": "^7.0.0",
+        "@babel/preset-env": "^7.4.5",
+        "@babel/preset-react": "^7.0.0",
+        "@svgr/core": "^4.3.3",
+        "@svgr/plugin-jsx": "^4.3.3",
+        "@svgr/plugin-svgo": "^4.3.1",
+        "loader-utils": "^1.2.3"
+      }
+    },
+    "@testing-library/dom": {
+      "version": "6.16.0",
+      "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-6.16.0.tgz",
+      "integrity": "sha512-lBD88ssxqEfz0wFL6MeUyyWZfV/2cjEZZV3YRpb2IoJRej/4f1jB0TzqIOznTpfR1r34CNesrubxwIlAQ8zgPA==",
+      "dev": true,
+      "requires": {
+        "@babel/runtime": "^7.8.4",
+        "@sheerun/mutationobserver-shim": "^0.3.2",
+        "@types/testing-library__dom": "^6.12.1",
+        "aria-query": "^4.0.2",
+        "dom-accessibility-api": "^0.3.0",
+        "pretty-format": "^25.1.0",
+        "wait-for-expect": "^3.0.2"
+      },
+      "dependencies": {
+        "@jest/types": {
+          "version": "25.5.0",
+          "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz",
+          "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==",
+          "dev": true,
+          "requires": {
+            "@types/istanbul-lib-coverage": "^2.0.0",
+            "@types/istanbul-reports": "^1.1.1",
+            "@types/yargs": "^15.0.0",
+            "chalk": "^3.0.0"
+          }
+        },
+        "@types/yargs": {
+          "version": "15.0.5",
+          "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz",
+          "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==",
+          "dev": true,
+          "requires": {
+            "@types/yargs-parser": "*"
+          }
+        },
+        "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"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "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
+        },
+        "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
+        },
+        "pretty-format": {
+          "version": "25.5.0",
+          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz",
+          "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^25.5.0",
+            "ansi-regex": "^5.0.0",
+            "ansi-styles": "^4.0.0",
+            "react-is": "^16.12.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"
+          }
+        }
+      }
+    },
+    "@testing-library/jest-dom": {
+      "version": "4.2.4",
+      "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-4.2.4.tgz",
+      "integrity": "sha512-j31Bn0rQo12fhCWOUWy9fl7wtqkp7In/YP2p5ZFyRuiiB9Qs3g+hS4gAmDWONbAHcRmVooNJ5eOHQDCOmUFXHg==",
+      "dev": true,
+      "requires": {
+        "@babel/runtime": "^7.5.1",
+        "chalk": "^2.4.1",
+        "css": "^2.2.3",
+        "css.escape": "^1.5.1",
+        "jest-diff": "^24.0.0",
+        "jest-matcher-utils": "^24.0.0",
+        "lodash": "^4.17.11",
+        "pretty-format": "^24.0.0",
+        "redent": "^3.0.0"
+      }
+    },
+    "@testing-library/react": {
+      "version": "9.5.0",
+      "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-9.5.0.tgz",
+      "integrity": "sha512-di1b+D0p+rfeboHO5W7gTVeZDIK5+maEgstrZbWZSSvxDyfDRkkyBE1AJR5Psd6doNldluXlCWqXriUfqu/9Qg==",
+      "dev": true,
+      "requires": {
+        "@babel/runtime": "^7.8.4",
+        "@testing-library/dom": "^6.15.0",
+        "@types/testing-library__react": "^9.1.2"
+      }
+    },
+    "@testing-library/user-event": {
+      "version": "7.2.1",
+      "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-7.2.1.tgz",
+      "integrity": "sha512-oZ0Ib5I4Z2pUEcoo95cT1cr6slco9WY7yiPpG+RGNkj8YcYgJnM7pXmYmorNOReh8MIGcKSqXyeGjxnr8YiZbA==",
+      "dev": true
+    },
+    "@types/babel__core": {
+      "version": "7.1.8",
+      "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.8.tgz",
+      "integrity": "sha512-KXBiQG2OXvaPWFPDS1rD8yV9vO0OuWIqAEqLsbfX0oU2REN5KuoMnZ1gClWcBhO5I3n6oTVAmrMufOvRqdmFTQ==",
+      "dev": true,
+      "requires": {
+        "@babel/parser": "^7.1.0",
+        "@babel/types": "^7.0.0",
+        "@types/babel__generator": "*",
+        "@types/babel__template": "*",
+        "@types/babel__traverse": "*"
+      }
+    },
+    "@types/babel__generator": {
+      "version": "7.6.1",
+      "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz",
+      "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "@types/babel__template": {
+      "version": "7.0.2",
+      "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz",
+      "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==",
+      "dev": true,
+      "requires": {
+        "@babel/parser": "^7.1.0",
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "@types/babel__traverse": {
+      "version": "7.0.12",
+      "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.12.tgz",
+      "integrity": "sha512-t4CoEokHTfcyfb4hUaF9oOHu9RmmNWnm1CP0YmMqOOfClKascOmvlEM736vlqeScuGvBDsHkf8R2INd4DWreQA==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.3.0"
+      }
+    },
+    "@types/color-name": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
+      "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
+      "dev": true
+    },
+    "@types/eslint-visitor-keys": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
+      "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==",
+      "dev": true
+    },
+    "@types/glob": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.2.tgz",
+      "integrity": "sha512-VgNIkxK+j7Nz5P7jvUZlRvhuPSmsEfS03b0alKcq5V/STUKAa3Plemsn5mrQUO7am6OErJ4rhGEGJbACclrtRA==",
+      "dev": true,
+      "requires": {
+        "@types/minimatch": "*",
+        "@types/node": "*"
+      }
+    },
+    "@types/history": {
+      "version": "4.7.6",
+      "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.6.tgz",
+      "integrity": "sha512-GRTZLeLJ8ia00ZH8mxMO8t0aC9M1N9bN461Z2eaRurJo6Fpa+utgCwLzI4jQHcrdzuzp5WPN9jRwpsCQ1VhJ5w==",
+      "dev": true
+    },
+    "@types/hoist-non-react-statics": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
+      "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
+      "dev": true,
+      "requires": {
+        "@types/react": "*",
+        "hoist-non-react-statics": "^3.3.0"
+      }
+    },
+    "@types/http-proxy": {
+      "version": "1.17.4",
+      "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.4.tgz",
+      "integrity": "sha512-IrSHl2u6AWXduUaDLqYpt45tLVCtYv7o4Z0s1KghBCDgIIS9oW5K1H8mZG/A2CfeLdEa7rTd1ACOiHBc1EMT2Q==",
+      "dev": true,
+      "requires": {
+        "@types/node": "*"
+      }
+    },
+    "@types/istanbul-lib-coverage": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.2.tgz",
+      "integrity": "sha512-rsZg7eL+Xcxsxk2XlBt9KcG8nOp9iYdKCOikY9x2RFJCyOdNj4MKPQty0e8oZr29vVAzKXr1BmR+kZauti3o1w==",
+      "dev": true
+    },
+    "@types/istanbul-lib-report": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+      "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==",
+      "dev": true,
+      "requires": {
+        "@types/istanbul-lib-coverage": "*"
+      }
+    },
+    "@types/istanbul-reports": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz",
+      "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==",
+      "dev": true,
+      "requires": {
+        "@types/istanbul-lib-coverage": "*",
+        "@types/istanbul-lib-report": "*"
+      }
+    },
+    "@types/jest": {
+      "version": "25.2.3",
+      "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.2.3.tgz",
+      "integrity": "sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw==",
+      "dev": true,
+      "requires": {
+        "jest-diff": "^25.2.1",
+        "pretty-format": "^25.2.1"
+      },
+      "dependencies": {
+        "@jest/types": {
+          "version": "25.5.0",
+          "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz",
+          "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==",
+          "dev": true,
+          "requires": {
+            "@types/istanbul-lib-coverage": "^2.0.0",
+            "@types/istanbul-reports": "^1.1.1",
+            "@types/yargs": "^15.0.0",
+            "chalk": "^3.0.0"
+          }
+        },
+        "@types/yargs": {
+          "version": "15.0.5",
+          "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz",
+          "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==",
+          "dev": true,
+          "requires": {
+            "@types/yargs-parser": "*"
+          }
+        },
+        "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"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "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
+        },
+        "diff-sequences": {
+          "version": "25.2.6",
+          "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz",
+          "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==",
+          "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
+        },
+        "jest-diff": {
+          "version": "25.5.0",
+          "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz",
+          "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==",
+          "dev": true,
+          "requires": {
+            "chalk": "^3.0.0",
+            "diff-sequences": "^25.2.6",
+            "jest-get-type": "^25.2.6",
+            "pretty-format": "^25.5.0"
+          }
+        },
+        "jest-get-type": {
+          "version": "25.2.6",
+          "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz",
+          "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==",
+          "dev": true
+        },
+        "pretty-format": {
+          "version": "25.5.0",
+          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz",
+          "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^25.5.0",
+            "ansi-regex": "^5.0.0",
+            "ansi-styles": "^4.0.0",
+            "react-is": "^16.12.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"
+          }
+        }
+      }
+    },
+    "@types/json-schema": {
+      "version": "7.0.4",
+      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz",
+      "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==",
+      "dev": true
+    },
+    "@types/lodash": {
+      "version": "4.14.155",
+      "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.155.tgz",
+      "integrity": "sha512-vEcX7S7aPhsBCivxMwAANQburHBtfN9RdyXFk84IJmu2Z4Hkg1tOFgaslRiEqqvoLtbCBi6ika1EMspE+NZ9Lg=="
+    },
+    "@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/minimist": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz",
+      "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=",
+      "dev": true
+    },
+    "@types/node": {
+      "version": "13.13.11",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.11.tgz",
+      "integrity": "sha512-FX7mIFKfnGCfq10DGWNhfCNxhACEeqH5uulT6wRRA1KEt7zgLe0HdrAd9/QQkObDqp2Z0KEV3OAmNgs0lTx5tQ==",
+      "dev": true
+    },
+    "@types/normalize-package-data": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+      "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
+      "dev": true
+    },
+    "@types/parse-json": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
+      "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
+      "dev": true
+    },
+    "@types/prop-types": {
+      "version": "15.7.3",
+      "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz",
+      "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==",
+      "dev": true
+    },
+    "@types/q": {
+      "version": "1.5.4",
+      "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz",
+      "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==",
+      "dev": true
+    },
+    "@types/react": {
+      "version": "16.9.35",
+      "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.35.tgz",
+      "integrity": "sha512-q0n0SsWcGc8nDqH2GJfWQWUOmZSJhXV64CjVN5SvcNti3TdEaA3AH0D8DwNmMdzjMAC/78tB8nAZIlV8yTz+zQ==",
+      "dev": true,
+      "requires": {
+        "@types/prop-types": "*",
+        "csstype": "^2.2.0"
+      }
+    },
+    "@types/react-dom": {
+      "version": "16.9.8",
+      "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.8.tgz",
+      "integrity": "sha512-ykkPQ+5nFknnlU6lDd947WbQ6TE3NNzbQAkInC2EKY1qeYdTKp7onFusmYZb+ityzx2YviqT6BXSu+LyWWJwcA==",
+      "dev": true,
+      "requires": {
+        "@types/react": "*"
+      }
+    },
+    "@types/react-redux": {
+      "version": "7.1.9",
+      "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.9.tgz",
+      "integrity": "sha512-mpC0jqxhP4mhmOl3P4ipRsgTgbNofMRXJb08Ms6gekViLj61v1hOZEKWDCyWsdONr6EjEA6ZHXC446wdywDe0w==",
+      "dev": true,
+      "requires": {
+        "@types/hoist-non-react-statics": "^3.3.0",
+        "@types/react": "*",
+        "hoist-non-react-statics": "^3.3.0",
+        "redux": "^4.0.0"
+      }
+    },
+    "@types/react-router": {
+      "version": "5.1.7",
+      "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.7.tgz",
+      "integrity": "sha512-2ouP76VQafKjtuc0ShpwUebhHwJo0G6rhahW9Pb8au3tQTjYXd2jta4wv6U2tGLR/I42yuG00+UXjNYY0dTzbg==",
+      "dev": true,
+      "requires": {
+        "@types/history": "*",
+        "@types/react": "*"
+      }
+    },
+    "@types/react-router-dom": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.5.tgz",
+      "integrity": "sha512-ArBM4B1g3BWLGbaGvwBGO75GNFbLDUthrDojV2vHLih/Tq8M+tgvY1DSwkuNrPSwdp/GUL93WSEpTZs8nVyJLw==",
+      "dev": true,
+      "requires": {
+        "@types/history": "*",
+        "@types/react": "*",
+        "@types/react-router": "*"
+      }
+    },
+    "@types/stack-utils": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
+      "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==",
+      "dev": true
+    },
+    "@types/testing-library__dom": {
+      "version": "6.14.0",
+      "resolved": "https://registry.npmjs.org/@types/testing-library__dom/-/testing-library__dom-6.14.0.tgz",
+      "integrity": "sha512-sMl7OSv0AvMOqn1UJ6j1unPMIHRXen0Ita1ujnMX912rrOcawe4f7wu0Zt9GIQhBhJvH2BaibqFgQ3lP+Pj2hA==",
+      "dev": true,
+      "requires": {
+        "pretty-format": "^24.3.0"
+      }
+    },
+    "@types/testing-library__react": {
+      "version": "9.1.3",
+      "resolved": "https://registry.npmjs.org/@types/testing-library__react/-/testing-library__react-9.1.3.tgz",
+      "integrity": "sha512-iCdNPKU3IsYwRK9JieSYAiX0+aYDXOGAmrC/3/M7AqqSDKnWWVv07X+Zk1uFSL7cMTUYzv4lQRfohucEocn5/w==",
+      "dev": true,
+      "requires": {
+        "@types/react-dom": "*",
+        "@types/testing-library__dom": "*",
+        "pretty-format": "^25.1.0"
+      },
+      "dependencies": {
+        "@jest/types": {
+          "version": "25.5.0",
+          "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz",
+          "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==",
+          "dev": true,
+          "requires": {
+            "@types/istanbul-lib-coverage": "^2.0.0",
+            "@types/istanbul-reports": "^1.1.1",
+            "@types/yargs": "^15.0.0",
+            "chalk": "^3.0.0"
+          }
+        },
+        "@types/yargs": {
+          "version": "15.0.5",
+          "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz",
+          "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==",
+          "dev": true,
+          "requires": {
+            "@types/yargs-parser": "*"
+          }
+        },
+        "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"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "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
+        },
+        "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
+        },
+        "pretty-format": {
+          "version": "25.5.0",
+          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz",
+          "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^25.5.0",
+            "ansi-regex": "^5.0.0",
+            "ansi-styles": "^4.0.0",
+            "react-is": "^16.12.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"
+          }
+        }
+      }
+    },
+    "@types/unist": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz",
+      "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==",
+      "dev": true
+    },
+    "@types/yargs": {
+      "version": "13.0.9",
+      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.9.tgz",
+      "integrity": "sha512-xrvhZ4DZewMDhoH1utLtOAwYQy60eYFoXeje30TzM3VOvQlBwQaEpKFq5m34k1wOw2AKIi2pwtiAjdmhvlBUzg==",
+      "dev": true,
+      "requires": {
+        "@types/yargs-parser": "*"
+      }
+    },
+    "@types/yargs-parser": {
+      "version": "15.0.0",
+      "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz",
+      "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==",
+      "dev": true
+    },
+    "@typescript-eslint/eslint-plugin": {
+      "version": "2.34.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz",
+      "integrity": "sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ==",
+      "dev": true,
+      "requires": {
+        "@typescript-eslint/experimental-utils": "2.34.0",
+        "functional-red-black-tree": "^1.0.1",
+        "regexpp": "^3.0.0",
+        "tsutils": "^3.17.1"
+      },
+      "dependencies": {
+        "regexpp": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
+          "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
+          "dev": true
+        }
+      }
+    },
+    "@typescript-eslint/experimental-utils": {
+      "version": "2.34.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz",
+      "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==",
+      "dev": true,
+      "requires": {
+        "@types/json-schema": "^7.0.3",
+        "@typescript-eslint/typescript-estree": "2.34.0",
+        "eslint-scope": "^5.0.0",
+        "eslint-utils": "^2.0.0"
+      },
+      "dependencies": {
+        "eslint-utils": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz",
+          "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==",
+          "dev": true,
+          "requires": {
+            "eslint-visitor-keys": "^1.1.0"
+          }
+        }
+      }
+    },
+    "@typescript-eslint/parser": {
+      "version": "2.34.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.34.0.tgz",
+      "integrity": "sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA==",
+      "dev": true,
+      "requires": {
+        "@types/eslint-visitor-keys": "^1.0.0",
+        "@typescript-eslint/experimental-utils": "2.34.0",
+        "@typescript-eslint/typescript-estree": "2.34.0",
+        "eslint-visitor-keys": "^1.1.0"
+      }
+    },
+    "@typescript-eslint/typescript-estree": {
+      "version": "2.34.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz",
+      "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==",
+      "dev": true,
+      "requires": {
+        "debug": "^4.1.1",
+        "eslint-visitor-keys": "^1.1.0",
+        "glob": "^7.1.6",
+        "is-glob": "^4.0.1",
+        "lodash": "^4.17.15",
+        "semver": "^7.3.2",
+        "tsutils": "^3.17.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        },
+        "semver": {
+          "version": "7.3.2",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
+          "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
+          "dev": true
+        }
+      }
+    },
+    "@umijs/route-utils": {
+      "version": "1.0.15",
+      "resolved": "https://registry.npmjs.org/@umijs/route-utils/-/route-utils-1.0.15.tgz",
+      "integrity": "sha512-xdvayCfjbxvgwRUyWe6ylkr9LgYc86mwU/BJo+z+p44NFpmhTgmCHFRm9e8XgFmj5DELWtLA4Y5gQPKaTs/6kQ==",
+      "requires": {
+        "hash.js": "^1.1.7",
+        "lodash.isequal": "^4.5.0",
+        "memoize-one": "^5.1.1",
+        "path-to-regexp": "2.4.0"
+      }
+    },
+    "@umijs/use-request": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/@umijs/use-request/-/use-request-1.4.3.tgz",
+      "integrity": "sha512-aH4GCdRnMCaaciygdN0KtCDQdBBh1KyiNUAgYDPX8Y4brmbymEpJViX1FU4isOTbV34WlbkWTiBpR9HIi2ciNQ==",
+      "requires": {
+        "lodash.debounce": "^4.0.8",
+        "lodash.throttle": "^4.1.1",
+        "umi-request": "^1.2.17"
+      }
+    },
+    "@webassemblyjs/ast": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
+      "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/helper-module-context": "1.8.5",
+        "@webassemblyjs/helper-wasm-bytecode": "1.8.5",
+        "@webassemblyjs/wast-parser": "1.8.5"
+      }
+    },
+    "@webassemblyjs/floating-point-hex-parser": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz",
+      "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-api-error": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz",
+      "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-buffer": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz",
+      "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-code-frame": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz",
+      "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/wast-printer": "1.8.5"
+      }
+    },
+    "@webassemblyjs/helper-fsm": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz",
+      "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-module-context": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz",
+      "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.8.5",
+        "mamacro": "^0.0.3"
+      }
+    },
+    "@webassemblyjs/helper-wasm-bytecode": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz",
+      "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-wasm-section": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz",
+      "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.8.5",
+        "@webassemblyjs/helper-buffer": "1.8.5",
+        "@webassemblyjs/helper-wasm-bytecode": "1.8.5",
+        "@webassemblyjs/wasm-gen": "1.8.5"
+      }
+    },
+    "@webassemblyjs/ieee754": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz",
+      "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==",
+      "dev": true,
+      "requires": {
+        "@xtuc/ieee754": "^1.2.0"
+      }
+    },
+    "@webassemblyjs/leb128": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz",
+      "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==",
+      "dev": true,
+      "requires": {
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@webassemblyjs/utf8": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz",
+      "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==",
+      "dev": true
+    },
+    "@webassemblyjs/wasm-edit": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz",
+      "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.8.5",
+        "@webassemblyjs/helper-buffer": "1.8.5",
+        "@webassemblyjs/helper-wasm-bytecode": "1.8.5",
+        "@webassemblyjs/helper-wasm-section": "1.8.5",
+        "@webassemblyjs/wasm-gen": "1.8.5",
+        "@webassemblyjs/wasm-opt": "1.8.5",
+        "@webassemblyjs/wasm-parser": "1.8.5",
+        "@webassemblyjs/wast-printer": "1.8.5"
+      }
+    },
+    "@webassemblyjs/wasm-gen": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz",
+      "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.8.5",
+        "@webassemblyjs/helper-wasm-bytecode": "1.8.5",
+        "@webassemblyjs/ieee754": "1.8.5",
+        "@webassemblyjs/leb128": "1.8.5",
+        "@webassemblyjs/utf8": "1.8.5"
+      }
+    },
+    "@webassemblyjs/wasm-opt": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz",
+      "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.8.5",
+        "@webassemblyjs/helper-buffer": "1.8.5",
+        "@webassemblyjs/wasm-gen": "1.8.5",
+        "@webassemblyjs/wasm-parser": "1.8.5"
+      }
+    },
+    "@webassemblyjs/wasm-parser": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz",
+      "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.8.5",
+        "@webassemblyjs/helper-api-error": "1.8.5",
+        "@webassemblyjs/helper-wasm-bytecode": "1.8.5",
+        "@webassemblyjs/ieee754": "1.8.5",
+        "@webassemblyjs/leb128": "1.8.5",
+        "@webassemblyjs/utf8": "1.8.5"
+      }
+    },
+    "@webassemblyjs/wast-parser": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz",
+      "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.8.5",
+        "@webassemblyjs/floating-point-hex-parser": "1.8.5",
+        "@webassemblyjs/helper-api-error": "1.8.5",
+        "@webassemblyjs/helper-code-frame": "1.8.5",
+        "@webassemblyjs/helper-fsm": "1.8.5",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@webassemblyjs/wast-printer": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz",
+      "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.8.5",
+        "@webassemblyjs/wast-parser": "1.8.5",
+        "@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
+    },
+    "JSONStream": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
+      "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
+      "dev": true,
+      "requires": {
+        "jsonparse": "^1.2.0",
+        "through": ">=2.2.7 <3"
+      }
+    },
+    "abab": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz",
+      "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==",
+      "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": "7.2.0",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz",
+      "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==",
+      "dev": true
+    },
+    "acorn-globals": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz",
+      "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==",
+      "dev": true,
+      "requires": {
+        "acorn": "^6.0.1",
+        "acorn-walk": "^6.0.1"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "6.4.1",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
+          "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==",
+          "dev": true
+        }
+      }
+    },
+    "acorn-jsx": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz",
+      "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==",
+      "dev": true
+    },
+    "acorn-walk": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz",
+      "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==",
+      "dev": true
+    },
+    "address": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz",
+      "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==",
+      "dev": true
+    },
+    "adjust-sourcemap-loader": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-2.0.0.tgz",
+      "integrity": "sha512-4hFsTsn58+YjrU9qKzML2JSSDqKvN8mUGQ0nNIrfPi8hmIONT4L3uUaT6MKdMsZ9AjsU6D2xDkZxCkbQPxChrA==",
+      "dev": true,
+      "requires": {
+        "assert": "1.4.1",
+        "camelcase": "5.0.0",
+        "loader-utils": "1.2.3",
+        "object-path": "0.11.4",
+        "regex-parser": "2.2.10"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz",
+          "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==",
+          "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
+        },
+        "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"
+          }
+        }
+      }
+    },
+    "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.12.2",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz",
+      "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==",
+      "dev": true,
+      "requires": {
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      }
+    },
+    "ajv-errors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
+      "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==",
+      "dev": true
+    },
+    "ajv-keywords": {
+      "version": "3.4.1",
+      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz",
+      "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==",
+      "dev": true
+    },
+    "alphanum-sort": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz",
+      "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
+      "dev": true
+    },
+    "ansi-colors": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
+      "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==",
+      "dev": true
+    },
+    "ansi-escapes": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
+      "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
+      "dev": true
+    },
+    "ansi-html": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz",
+      "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=",
+      "dev": true
+    },
+    "ansi-regex": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+      "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+      "dev": true
+    },
+    "ansi-styles": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "dev": true,
+      "requires": {
+        "color-convert": "^1.9.0"
+      }
+    },
+    "antd": {
+      "version": "4.3.3",
+      "resolved": "https://registry.npmjs.org/antd/-/antd-4.3.3.tgz",
+      "integrity": "sha512-psDb3krf0nK0gkZSfxOGfJdqKbi0hzQJif7R2Cg3T6OV1nrNfc6waL4Th8mV72qq/+Ushuk0afRDaARkx9EzEg==",
+      "requires": {
+        "@ant-design/css-animation": "^1.7.2",
+        "@ant-design/icons": "^4.2.1",
+        "@ant-design/react-slick": "~0.26.1",
+        "array-tree-filter": "^2.1.0",
+        "classnames": "^2.2.6",
+        "copy-to-clipboard": "^3.2.0",
+        "lodash": "^4.17.13",
+        "moment": "^2.25.3",
+        "omit.js": "^1.0.2",
+        "raf": "^3.4.1",
+        "rc-animate": "~3.1.0",
+        "rc-cascader": "~1.2.0",
+        "rc-checkbox": "~2.2.0",
+        "rc-collapse": "~2.0.0",
+        "rc-dialog": "~8.0.0",
+        "rc-drawer": "~4.0.0",
+        "rc-dropdown": "~3.1.2",
+        "rc-field-form": "~1.4.1",
+        "rc-input-number": "~5.0.0",
+        "rc-mentions": "~1.2.0",
+        "rc-menu": "~8.3.0",
+        "rc-notification": "~4.4.0",
+        "rc-pagination": "~2.2.5",
+        "rc-picker": "~1.6.1",
+        "rc-progress": "~3.0.0",
+        "rc-rate": "~2.7.0",
+        "rc-resize-observer": "^0.2.3",
+        "rc-select": "~11.0.0",
+        "rc-slider": "~9.3.0",
+        "rc-steps": "~4.0.0",
+        "rc-switch": "~3.2.0",
+        "rc-table": "~7.7.2",
+        "rc-tabs": "~11.3.1",
+        "rc-tooltip": "~4.2.0",
+        "rc-tree": "~3.3.0",
+        "rc-tree-select": "~4.0.0",
+        "rc-trigger": "~4.3.0",
+        "rc-upload": "~3.1.0",
+        "rc-util": "^5.0.1",
+        "scroll-into-view-if-needed": "^2.2.25",
+        "warning": "^4.0.3"
+      }
+    },
+    "antd-dayjs-webpack-plugin": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/antd-dayjs-webpack-plugin/-/antd-dayjs-webpack-plugin-1.0.0.tgz",
+      "integrity": "sha512-Ix/k8HZxZA7v+Uh+hI3Pw3+fSTlwEnsccFqTZmAeHN1gXSt2vXLXK20KUOZphVgF8zf2zwPpJPlQWvC7TG7lHQ==",
+      "dev": true,
+      "requires": {
+        "dayjs": "*"
+      }
+    },
+    "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"
+          }
+        }
+      }
+    },
+    "aproba": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
+      "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"
+      }
+    },
+    "aria-query": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.0.2.tgz",
+      "integrity": "sha512-S1G1V790fTaigUSM/Gd0NngzEfiMy9uTUfMyHhKhVyy4cH5O/eTuR01ydhGL0z4Za1PXFTRGH3qL8VhUQuEO5w==",
+      "dev": true,
+      "requires": {
+        "@babel/runtime": "^7.7.4",
+        "@babel/runtime-corejs3": "^7.7.4"
+      }
+    },
+    "arity-n": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz",
+      "integrity": "sha1-2edrEXM+CFacCEeuezmyhgswt0U=",
+      "dev": true
+    },
+    "arr-diff": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+      "dev": true
+    },
+    "arr-flatten": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+      "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+      "dev": true
+    },
+    "arr-union": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+      "dev": true
+    },
+    "array-equal": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
+      "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=",
+      "dev": true
+    },
+    "array-find-index": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+      "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
+      "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-ify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz",
+      "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=",
+      "dev": true
+    },
+    "array-includes": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz",
+      "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.0",
+        "is-string": "^1.0.5"
+      }
+    },
+    "array-tree-filter": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz",
+      "integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw=="
+    },
+    "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.flat": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz",
+      "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.0-next.1"
+      }
+    },
+    "arrify": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
+      "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
+      "dev": true
+    },
+    "asap": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+      "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=",
+      "dev": true
+    },
+    "asn1": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+      "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+      "dev": true,
+      "requires": {
+        "safer-buffer": "~2.1.0"
+      }
+    },
+    "asn1.js": {
+      "version": "4.10.1",
+      "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
+      "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "assert": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
+      "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
+      "dev": true,
+      "requires": {
+        "util": "0.10.3"
+      }
+    },
+    "assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+      "dev": true
+    },
+    "assign-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "dev": true
+    },
+    "ast-types-flow": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz",
+      "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=",
+      "dev": true
+    },
+    "astral-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
+      "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
+      "dev": true
+    },
+    "async": {
+      "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
+    },
+    "async-validator": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-3.3.0.tgz",
+      "integrity": "sha512-cAHGD9EL8aCqWXjnb44q94MWiDFzUo1tMhvLb2WzcpWqGiKugsjWG9cvl+jPgkPca7asNbsBU3fa0cwkI/P+Xg=="
+    },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+      "dev": true
+    },
+    "atob": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+      "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+      "dev": true
+    },
+    "autoprefixer": {
+      "version": "9.8.0",
+      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.0.tgz",
+      "integrity": "sha512-D96ZiIHXbDmU02dBaemyAg53ez+6F5yZmapmgKcjm35yEe1uVDYI8hGW3VYoGRaG290ZFf91YxHrR518vC0u/A==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.12.0",
+        "caniuse-lite": "^1.0.30001061",
+        "chalk": "^2.4.2",
+        "normalize-range": "^0.1.2",
+        "num2fraction": "^1.2.2",
+        "postcss": "^7.0.30",
+        "postcss-value-parser": "^4.1.0"
+      }
+    },
+    "aws-sign2": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+      "dev": true
+    },
+    "aws4": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz",
+      "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==",
+      "dev": true
+    },
+    "axios": {
+      "version": "0.19.2",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
+      "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
+      "requires": {
+        "follow-redirects": "1.5.10"
+      }
+    },
+    "axobject-query": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.1.2.tgz",
+      "integrity": "sha512-ICt34ZmrVt8UQnvPl6TVyDTkmhXmAyAT4Jh5ugfGUX4MOrZ+U/ZY6/sdylRw3qGNr9Ub5AJsaHeDMzNLehRdOQ==",
+      "dev": true
+    },
+    "babel-code-frame": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+      "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+      "dev": true,
+      "requires": {
+        "chalk": "^1.1.3",
+        "esutils": "^2.0.2",
+        "js-tokens": "^3.0.2"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "2.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+          "dev": true
+        },
+        "chalk": {
+          "version": "1.1.3",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^2.2.1",
+            "escape-string-regexp": "^1.0.2",
+            "has-ansi": "^2.0.0",
+            "strip-ansi": "^3.0.0",
+            "supports-color": "^2.0.0"
+          }
+        },
+        "js-tokens": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+          "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^2.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+          "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+          "dev": true
+        }
+      }
+    },
+    "babel-eslint": {
+      "version": "10.0.3",
+      "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.3.tgz",
+      "integrity": "sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.0.0",
+        "@babel/parser": "^7.0.0",
+        "@babel/traverse": "^7.0.0",
+        "@babel/types": "^7.0.0",
+        "eslint-visitor-keys": "^1.0.0",
+        "resolve": "^1.12.0"
+      }
+    },
+    "babel-extract-comments": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz",
+      "integrity": "sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ==",
+      "dev": true,
+      "requires": {
+        "babylon": "^6.18.0"
+      }
+    },
+    "babel-jest": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz",
+      "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==",
+      "dev": true,
+      "requires": {
+        "@jest/transform": "^24.9.0",
+        "@jest/types": "^24.9.0",
+        "@types/babel__core": "^7.1.0",
+        "babel-plugin-istanbul": "^5.1.0",
+        "babel-preset-jest": "^24.9.0",
+        "chalk": "^2.4.2",
+        "slash": "^2.0.0"
+      },
+      "dependencies": {
+        "slash": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+          "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+          "dev": true
+        }
+      }
+    },
+    "babel-loader": {
+      "version": "8.0.6",
+      "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.6.tgz",
+      "integrity": "sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw==",
+      "dev": true,
+      "requires": {
+        "find-cache-dir": "^2.0.0",
+        "loader-utils": "^1.0.2",
+        "mkdirp": "^0.5.1",
+        "pify": "^4.0.1"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+          "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+          "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"
+      }
+    },
+    "babel-plugin-import": {
+      "version": "1.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-import/-/babel-plugin-import-1.13.0.tgz",
+      "integrity": "sha512-bHU8m0SrY89ub2hBBuYjbennOeH0YUYkVpH6jxKFk0uD8rhN+0jNHIPtXnac+Vn7N/hgkLGGDcIoYK7je3Hhew==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.0.0",
+        "@babel/runtime": "^7.0.0"
+      }
+    },
+    "babel-plugin-istanbul": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz",
+      "integrity": "sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "find-up": "^3.0.0",
+        "istanbul-lib-instrument": "^3.3.0",
+        "test-exclude": "^5.2.3"
+      },
+      "dependencies": {
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^3.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "p-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
+        }
+      }
+    },
+    "babel-plugin-jest-hoist": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz",
+      "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==",
+      "dev": true,
+      "requires": {
+        "@types/babel__traverse": "^7.0.6"
+      }
+    },
+    "babel-plugin-macros": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz",
+      "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==",
+      "dev": true,
+      "requires": {
+        "@babel/runtime": "^7.7.2",
+        "cosmiconfig": "^6.0.0",
+        "resolve": "^1.12.0"
+      },
+      "dependencies": {
+        "cosmiconfig": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
+          "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==",
+          "dev": true,
+          "requires": {
+            "@types/parse-json": "^4.0.0",
+            "import-fresh": "^3.1.0",
+            "parse-json": "^5.0.0",
+            "path-type": "^4.0.0",
+            "yaml": "^1.7.2"
+          }
+        },
+        "path-type": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+          "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+          "dev": true
+        }
+      }
+    },
+    "babel-plugin-named-asset-import": {
+      "version": "0.3.6",
+      "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.6.tgz",
+      "integrity": "sha512-1aGDUfL1qOOIoqk9QKGIo2lANk+C7ko/fqH0uIyC71x3PEGz0uVP8ISgfEsFuG+FKmjHTvFK/nNM8dowpmUxLA==",
+      "dev": true
+    },
+    "babel-plugin-syntax-object-rest-spread": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
+      "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
+      "dev": true
+    },
+    "babel-plugin-transform-object-rest-spread": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz",
+      "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-object-rest-spread": "^6.8.0",
+        "babel-runtime": "^6.26.0"
+      }
+    },
+    "babel-plugin-transform-react-remove-prop-types": {
+      "version": "0.4.24",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz",
+      "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==",
+      "dev": true
+    },
+    "babel-polyfill": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz",
+      "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "^6.26.0",
+        "core-js": "^2.5.0",
+        "regenerator-runtime": "^0.10.5"
+      },
+      "dependencies": {
+        "regenerator-runtime": {
+          "version": "0.10.5",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz",
+          "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=",
+          "dev": true
+        }
+      }
+    },
+    "babel-preset-jest": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz",
+      "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==",
+      "dev": true,
+      "requires": {
+        "@babel/plugin-syntax-object-rest-spread": "^7.0.0",
+        "babel-plugin-jest-hoist": "^24.9.0"
+      }
+    },
+    "babel-preset-react-app": {
+      "version": "9.1.2",
+      "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-9.1.2.tgz",
+      "integrity": "sha512-k58RtQOKH21NyKtzptoAvtAODuAJJs3ZhqBMl456/GnXEQ/0La92pNmwgWoMn5pBTrsvk3YYXdY7zpY4e3UIxA==",
+      "dev": true,
+      "requires": {
+        "@babel/core": "7.9.0",
+        "@babel/plugin-proposal-class-properties": "7.8.3",
+        "@babel/plugin-proposal-decorators": "7.8.3",
+        "@babel/plugin-proposal-nullish-coalescing-operator": "7.8.3",
+        "@babel/plugin-proposal-numeric-separator": "7.8.3",
+        "@babel/plugin-proposal-optional-chaining": "7.9.0",
+        "@babel/plugin-transform-flow-strip-types": "7.9.0",
+        "@babel/plugin-transform-react-display-name": "7.8.3",
+        "@babel/plugin-transform-runtime": "7.9.0",
+        "@babel/preset-env": "7.9.0",
+        "@babel/preset-react": "7.9.1",
+        "@babel/preset-typescript": "7.9.0",
+        "@babel/runtime": "7.9.0",
+        "babel-plugin-macros": "2.8.0",
+        "babel-plugin-transform-react-remove-prop-types": "0.4.24"
+      },
+      "dependencies": {
+        "@babel/core": {
+          "version": "7.9.0",
+          "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz",
+          "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.8.3",
+            "@babel/generator": "^7.9.0",
+            "@babel/helper-module-transforms": "^7.9.0",
+            "@babel/helpers": "^7.9.0",
+            "@babel/parser": "^7.9.0",
+            "@babel/template": "^7.8.6",
+            "@babel/traverse": "^7.9.0",
+            "@babel/types": "^7.9.0",
+            "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"
+          }
+        },
+        "@babel/plugin-proposal-class-properties": {
+          "version": "7.8.3",
+          "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz",
+          "integrity": "sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-create-class-features-plugin": "^7.8.3",
+            "@babel/helper-plugin-utils": "^7.8.3"
+          }
+        },
+        "@babel/plugin-proposal-nullish-coalescing-operator": {
+          "version": "7.8.3",
+          "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz",
+          "integrity": "sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-plugin-utils": "^7.8.3",
+            "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0"
+          }
+        },
+        "@babel/plugin-proposal-numeric-separator": {
+          "version": "7.8.3",
+          "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz",
+          "integrity": "sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-plugin-utils": "^7.8.3",
+            "@babel/plugin-syntax-numeric-separator": "^7.8.3"
+          }
+        },
+        "@babel/plugin-proposal-optional-chaining": {
+          "version": "7.9.0",
+          "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz",
+          "integrity": "sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-plugin-utils": "^7.8.3",
+            "@babel/plugin-syntax-optional-chaining": "^7.8.0"
+          }
+        },
+        "@babel/plugin-transform-react-display-name": {
+          "version": "7.8.3",
+          "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.8.3.tgz",
+          "integrity": "sha512-3Jy/PCw8Fe6uBKtEgz3M82ljt+lTg+xJaM4og+eyu83qLT87ZUSckn0wy7r31jflURWLO83TW6Ylf7lyXj3m5A==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-plugin-utils": "^7.8.3"
+          }
+        },
+        "@babel/preset-env": {
+          "version": "7.9.0",
+          "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.9.0.tgz",
+          "integrity": "sha512-712DeRXT6dyKAM/FMbQTV/FvRCms2hPCx+3weRjZ8iQVQWZejWWk1wwG6ViWMyqb/ouBbGOl5b6aCk0+j1NmsQ==",
+          "dev": true,
+          "requires": {
+            "@babel/compat-data": "^7.9.0",
+            "@babel/helper-compilation-targets": "^7.8.7",
+            "@babel/helper-module-imports": "^7.8.3",
+            "@babel/helper-plugin-utils": "^7.8.3",
+            "@babel/plugin-proposal-async-generator-functions": "^7.8.3",
+            "@babel/plugin-proposal-dynamic-import": "^7.8.3",
+            "@babel/plugin-proposal-json-strings": "^7.8.3",
+            "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3",
+            "@babel/plugin-proposal-numeric-separator": "^7.8.3",
+            "@babel/plugin-proposal-object-rest-spread": "^7.9.0",
+            "@babel/plugin-proposal-optional-catch-binding": "^7.8.3",
+            "@babel/plugin-proposal-optional-chaining": "^7.9.0",
+            "@babel/plugin-proposal-unicode-property-regex": "^7.8.3",
+            "@babel/plugin-syntax-async-generators": "^7.8.0",
+            "@babel/plugin-syntax-dynamic-import": "^7.8.0",
+            "@babel/plugin-syntax-json-strings": "^7.8.0",
+            "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0",
+            "@babel/plugin-syntax-numeric-separator": "^7.8.0",
+            "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+            "@babel/plugin-syntax-optional-catch-binding": "^7.8.0",
+            "@babel/plugin-syntax-optional-chaining": "^7.8.0",
+            "@babel/plugin-syntax-top-level-await": "^7.8.3",
+            "@babel/plugin-transform-arrow-functions": "^7.8.3",
+            "@babel/plugin-transform-async-to-generator": "^7.8.3",
+            "@babel/plugin-transform-block-scoped-functions": "^7.8.3",
+            "@babel/plugin-transform-block-scoping": "^7.8.3",
+            "@babel/plugin-transform-classes": "^7.9.0",
+            "@babel/plugin-transform-computed-properties": "^7.8.3",
+            "@babel/plugin-transform-destructuring": "^7.8.3",
+            "@babel/plugin-transform-dotall-regex": "^7.8.3",
+            "@babel/plugin-transform-duplicate-keys": "^7.8.3",
+            "@babel/plugin-transform-exponentiation-operator": "^7.8.3",
+            "@babel/plugin-transform-for-of": "^7.9.0",
+            "@babel/plugin-transform-function-name": "^7.8.3",
+            "@babel/plugin-transform-literals": "^7.8.3",
+            "@babel/plugin-transform-member-expression-literals": "^7.8.3",
+            "@babel/plugin-transform-modules-amd": "^7.9.0",
+            "@babel/plugin-transform-modules-commonjs": "^7.9.0",
+            "@babel/plugin-transform-modules-systemjs": "^7.9.0",
+            "@babel/plugin-transform-modules-umd": "^7.9.0",
+            "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3",
+            "@babel/plugin-transform-new-target": "^7.8.3",
+            "@babel/plugin-transform-object-super": "^7.8.3",
+            "@babel/plugin-transform-parameters": "^7.8.7",
+            "@babel/plugin-transform-property-literals": "^7.8.3",
+            "@babel/plugin-transform-regenerator": "^7.8.7",
+            "@babel/plugin-transform-reserved-words": "^7.8.3",
+            "@babel/plugin-transform-shorthand-properties": "^7.8.3",
+            "@babel/plugin-transform-spread": "^7.8.3",
+            "@babel/plugin-transform-sticky-regex": "^7.8.3",
+            "@babel/plugin-transform-template-literals": "^7.8.3",
+            "@babel/plugin-transform-typeof-symbol": "^7.8.4",
+            "@babel/plugin-transform-unicode-regex": "^7.8.3",
+            "@babel/preset-modules": "^0.1.3",
+            "@babel/types": "^7.9.0",
+            "browserslist": "^4.9.1",
+            "core-js-compat": "^3.6.2",
+            "invariant": "^2.2.2",
+            "levenary": "^1.1.1",
+            "semver": "^5.5.0"
+          }
+        },
+        "@babel/preset-react": {
+          "version": "7.9.1",
+          "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.9.1.tgz",
+          "integrity": "sha512-aJBYF23MPj0RNdp/4bHnAP0NVqqZRr9kl0NAOP4nJCex6OYVio59+dnQzsAWFuogdLyeaKA1hmfUIVZkY5J+TQ==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-plugin-utils": "^7.8.3",
+            "@babel/plugin-transform-react-display-name": "^7.8.3",
+            "@babel/plugin-transform-react-jsx": "^7.9.1",
+            "@babel/plugin-transform-react-jsx-development": "^7.9.0",
+            "@babel/plugin-transform-react-jsx-self": "^7.9.0",
+            "@babel/plugin-transform-react-jsx-source": "^7.9.0"
+          }
+        },
+        "@babel/runtime": {
+          "version": "7.9.0",
+          "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.0.tgz",
+          "integrity": "sha512-cTIudHnzuWLS56ik4DnRnqqNf8MkdUzV4iFFI1h7Jo9xvrpQROYaAnaSd2mHLQAzzZAPfATynX5ord6YlNYNMA==",
+          "dev": true,
+          "requires": {
+            "regenerator-runtime": "^0.13.4"
+          }
+        },
+        "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"
+          }
+        },
+        "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"
+          }
+        },
+        "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
+        },
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+          "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
+        }
+      }
+    },
+    "babel-runtime": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+      "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+      "requires": {
+        "core-js": "^2.4.0",
+        "regenerator-runtime": "^0.11.0"
+      },
+      "dependencies": {
+        "regenerator-runtime": {
+          "version": "0.11.1",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+          "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
+        }
+      }
+    },
+    "babylon": {
+      "version": "6.18.0",
+      "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+      "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
+      "dev": true
+    },
+    "bail": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz",
+      "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==",
+      "dev": true
+    },
+    "balanced-match": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+      "dev": true
+    },
+    "base": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+      "dev": true,
+      "requires": {
+        "cache-base": "^1.0.1",
+        "class-utils": "^0.3.5",
+        "component-emitter": "^1.2.1",
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.1",
+        "mixin-deep": "^1.2.0",
+        "pascalcase": "^0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "base64-js": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
+      "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==",
+      "dev": true
+    },
+    "batch": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
+      "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
+      "dev": true
+    },
+    "bcrypt-pbkdf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+      "dev": true,
+      "requires": {
+        "tweetnacl": "^0.14.3"
+      }
+    },
+    "big.js": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+      "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+      "dev": true
+    },
+    "binary-extensions": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz",
+      "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==",
+      "dev": true
+    },
+    "bindings": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+      "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "file-uri-to-path": "1.0.0"
+      }
+    },
+    "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"
+          }
+        },
+        "qs": {
+          "version": "6.7.0",
+          "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+          "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+          "dev": true
+        }
+      }
+    },
+    "bonjour": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz",
+      "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=",
+      "dev": true,
+      "requires": {
+        "array-flatten": "^2.1.0",
+        "deep-equal": "^1.0.1",
+        "dns-equal": "^1.0.0",
+        "dns-txt": "^2.0.2",
+        "multicast-dns": "^6.0.1",
+        "multicast-dns-service-types": "^1.1.0"
+      }
+    },
+    "boolbase": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+      "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
+      "dev": true
+    },
+    "brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
+      "requires": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "braces": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+      "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+      "dev": true,
+      "requires": {
+        "arr-flatten": "^1.1.0",
+        "array-unique": "^0.3.2",
+        "extend-shallow": "^2.0.1",
+        "fill-range": "^4.0.0",
+        "isobject": "^3.0.1",
+        "repeat-element": "^1.1.2",
+        "snapdragon": "^0.8.1",
+        "snapdragon-node": "^2.0.1",
+        "split-string": "^3.0.2",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "brorand": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+      "dev": true
+    },
+    "browser-process-hrtime": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
+      "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==",
+      "dev": true
+    },
+    "browser-resolve": {
+      "version": "1.11.3",
+      "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz",
+      "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==",
+      "dev": true,
+      "requires": {
+        "resolve": "1.1.7"
+      },
+      "dependencies": {
+        "resolve": {
+          "version": "1.1.7",
+          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+          "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
+          "dev": true
+        }
+      }
+    },
+    "browserify-aes": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+      "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+      "dev": true,
+      "requires": {
+        "buffer-xor": "^1.0.3",
+        "cipher-base": "^1.0.0",
+        "create-hash": "^1.1.0",
+        "evp_bytestokey": "^1.0.3",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "browserify-cipher": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+      "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+      "dev": true,
+      "requires": {
+        "browserify-aes": "^1.0.4",
+        "browserify-des": "^1.0.0",
+        "evp_bytestokey": "^1.0.0"
+      }
+    },
+    "browserify-des": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
+      "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.1",
+        "des.js": "^1.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "browserify-rsa": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+      "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "randombytes": "^2.0.1"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "browserify-sign": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.0.tgz",
+      "integrity": "sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^5.1.1",
+        "browserify-rsa": "^4.0.1",
+        "create-hash": "^1.2.0",
+        "create-hmac": "^1.1.7",
+        "elliptic": "^6.5.2",
+        "inherits": "^2.0.4",
+        "parse-asn1": "^5.1.5",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.2.1",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+          "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+          "dev": true
+        }
+      }
+    },
+    "browserify-zlib": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+      "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
+      "dev": true,
+      "requires": {
+        "pako": "~1.0.5"
+      }
+    },
+    "browserslist": {
+      "version": "4.12.0",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.0.tgz",
+      "integrity": "sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg==",
+      "dev": true,
+      "requires": {
+        "caniuse-lite": "^1.0.30001043",
+        "electron-to-chromium": "^1.3.413",
+        "node-releases": "^1.1.53",
+        "pkg-up": "^2.0.0"
+      }
+    },
+    "bser": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
+      "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
+      "dev": true,
+      "requires": {
+        "node-int64": "^0.4.0"
+      }
+    },
+    "btoa": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz",
+      "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==",
+      "dev": true
+    },
+    "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"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        }
+      }
+    },
+    "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": "13.0.1",
+      "resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz",
+      "integrity": "sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w==",
+      "dev": true,
+      "requires": {
+        "chownr": "^1.1.2",
+        "figgy-pudding": "^3.5.1",
+        "fs-minipass": "^2.0.0",
+        "glob": "^7.1.4",
+        "graceful-fs": "^4.2.2",
+        "infer-owner": "^1.0.4",
+        "lru-cache": "^5.1.1",
+        "minipass": "^3.0.0",
+        "minipass-collect": "^1.0.2",
+        "minipass-flush": "^1.0.5",
+        "minipass-pipeline": "^1.2.2",
+        "mkdirp": "^0.5.1",
+        "move-concurrently": "^1.0.1",
+        "p-map": "^3.0.0",
+        "promise-inflight": "^1.0.1",
+        "rimraf": "^2.7.1",
+        "ssri": "^7.0.0",
+        "unique-filename": "^1.1.1"
+      },
+      "dependencies": {
+        "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"
+          }
+        }
+      }
+    },
+    "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"
+      }
+    },
+    "cachedir": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.2.0.tgz",
+      "integrity": "sha512-VvxA0xhNqIIfg0V9AmJkDg91DaJwryutH5rVEZAhcNi4iJFj9f+QxmAjgK1LT9I8OgToX27fypX6/MeCXVbBjQ==",
+      "dev": true
+    },
+    "call-me-maybe": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz",
+      "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=",
+      "dev": true
+    },
+    "caller-callsite": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
+      "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=",
+      "dev": true,
+      "requires": {
+        "callsites": "^2.0.0"
+      },
+      "dependencies": {
+        "callsites": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
+          "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
+          "dev": true
+        }
+      }
+    },
+    "caller-path": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz",
+      "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=",
+      "dev": true,
+      "requires": {
+        "caller-callsite": "^2.0.0"
+      }
+    },
+    "callsites": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+      "dev": true
+    },
+    "camel-case": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.1.tgz",
+      "integrity": "sha512-7fa2WcG4fYFkclIvEmxBbTvmibwF2/agfEBc6q3lOpVu0A13ltLsA+Hr/8Hp6kp5f+G7hKi6t8lys6XxP+1K6Q==",
+      "dev": true,
+      "requires": {
+        "pascal-case": "^3.1.1",
+        "tslib": "^1.10.0"
+      }
+    },
+    "camelcase": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz",
+      "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==",
+      "dev": true
+    },
+    "camelcase-keys": {
+      "version": "6.2.2",
+      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz",
+      "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==",
+      "dev": true,
+      "requires": {
+        "camelcase": "^5.3.1",
+        "map-obj": "^4.0.0",
+        "quick-lru": "^4.0.1"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "5.3.1",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+          "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+          "dev": true
+        }
+      }
+    },
+    "caniuse-api": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
+      "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.0.0",
+        "caniuse-lite": "^1.0.0",
+        "lodash.memoize": "^4.1.2",
+        "lodash.uniq": "^4.5.0"
+      }
+    },
+    "caniuse-lite": {
+      "version": "1.0.30001079",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001079.tgz",
+      "integrity": "sha512-2KaYheg0iOY+CMmDuAB3DHehrXhhb4OZU4KBVGDr/YKyYAcpudaiUQ9PJ9rxrPlKEoJ3ATasQ5AN48MqpwS43Q==",
+      "dev": true
+    },
+    "capture-exit": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz",
+      "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==",
+      "dev": true,
+      "requires": {
+        "rsvp": "^4.8.4"
+      }
+    },
+    "case-sensitive-paths-webpack-plugin": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz",
+      "integrity": "sha512-/4YgnZS8y1UXXmC02xD5rRrBEu6T5ub+mQHLNRj0fzTRbgdBYhsNo2V5EqwgqrExjxsjtF/OpAKAMkKsxbD5XQ==",
+      "dev": true
+    },
+    "caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+      "dev": true
+    },
+    "ccount": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.5.tgz",
+      "integrity": "sha512-MOli1W+nfbPLlKEhInaxhRdp7KVLFxLN5ykwzHgLsLI3H3gs5jjFAK4Eoj3OzzcxCtumDaI8onoVDeQyWaNTkw==",
+      "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"
+      }
+    },
+    "character-entities": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz",
+      "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==",
+      "dev": true
+    },
+    "character-entities-html4": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz",
+      "integrity": "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==",
+      "dev": true
+    },
+    "character-entities-legacy": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz",
+      "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==",
+      "dev": true
+    },
+    "character-reference-invalid": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz",
+      "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==",
+      "dev": true
+    },
+    "chardet": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+      "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
+      "dev": true
+    },
+    "chokidar": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz",
+      "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==",
+      "dev": true,
+      "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": {
+        "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"
+          }
+        },
+        "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"
+          }
+        },
+        "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"
+          }
+        },
+        "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
+        },
+        "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"
+          }
+        }
+      }
+    },
+    "chownr": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+      "dev": true
+    },
+    "chrome-trace-event": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz",
+      "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==",
+      "dev": true,
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "ci-info": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+      "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+      "dev": true
+    },
+    "cipher-base": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+      "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "class-utils": {
+      "version": "0.3.6",
+      "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+      "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+      "dev": true,
+      "requires": {
+        "arr-union": "^3.1.0",
+        "define-property": "^0.2.5",
+        "isobject": "^3.0.0",
+        "static-extend": "^0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        }
+      }
+    },
+    "classnames": {
+      "version": "2.2.6",
+      "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
+      "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
+    },
+    "clean-css": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz",
+      "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==",
+      "dev": true,
+      "requires": {
+        "source-map": "~0.6.0"
+      }
+    },
+    "clean-stack": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+      "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+      "dev": true
+    },
+    "cli-cursor": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+      "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+      "dev": true,
+      "requires": {
+        "restore-cursor": "^2.0.0"
+      }
+    },
+    "cli-truncate": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz",
+      "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==",
+      "dev": true,
+      "requires": {
+        "slice-ansi": "^3.0.0",
+        "string-width": "^4.2.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
+        },
+        "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"
+          }
+        },
+        "astral-regex": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
+          "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
+          "dev": true
+        },
+        "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
+        },
+        "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
+        },
+        "slice-ansi": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz",
+          "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.0.0",
+            "astral-regex": "^2.0.0",
+            "is-fullwidth-code-point": "^3.0.0"
+          }
+        },
+        "string-width": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+          "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^8.0.0",
+            "is-fullwidth-code-point": "^3.0.0",
+            "strip-ansi": "^6.0.0"
+          }
+        },
+        "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"
+          }
+        }
+      }
+    },
+    "cli-width": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz",
+      "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==",
+      "dev": true
+    },
+    "cliui": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+      "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+      "dev": true,
+      "requires": {
+        "string-width": "^3.1.0",
+        "strip-ansi": "^5.2.0",
+        "wrap-ansi": "^5.1.0"
+      },
+      "dependencies": {
+        "emoji-regex": {
+          "version": "7.0.3",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+          "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+          "dev": true
+        },
+        "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"
+          }
+        },
+        "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"
+          }
+        }
+      }
+    },
+    "clone": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+      "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+      "dev": true
+    },
+    "clone-deep": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-0.2.4.tgz",
+      "integrity": "sha1-TnPdCen7lxzDhnDF3O2cGJZIHMY=",
+      "dev": true,
+      "requires": {
+        "for-own": "^0.1.3",
+        "is-plain-object": "^2.0.1",
+        "kind-of": "^3.0.2",
+        "lazy-cache": "^1.0.3",
+        "shallow-clone": "^0.1.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "clone-regexp": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz",
+      "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==",
+      "dev": true,
+      "requires": {
+        "is-regexp": "^2.0.0"
+      },
+      "dependencies": {
+        "is-regexp": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz",
+          "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==",
+          "dev": true
+        }
+      }
+    },
+    "co": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+      "dev": true
+    },
+    "coa": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz",
+      "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==",
+      "dev": true,
+      "requires": {
+        "@types/q": "^1.5.1",
+        "chalk": "^2.4.1",
+        "q": "^1.1.2"
+      }
+    },
+    "code-point-at": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+      "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+      "dev": true
+    },
+    "collapse-white-space": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz",
+      "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==",
+      "dev": true
+    },
+    "collection-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+      "dev": true,
+      "requires": {
+        "map-visit": "^1.0.0",
+        "object-visit": "^1.0.0"
+      }
+    },
+    "color": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz",
+      "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==",
+      "dev": true,
+      "requires": {
+        "color-convert": "^1.9.1",
+        "color-string": "^1.5.2"
+      }
+    },
+    "color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "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
+    },
+    "color-string": {
+      "version": "1.5.3",
+      "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
+      "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
+      "dev": true,
+      "requires": {
+        "color-name": "^1.0.0",
+        "simple-swizzle": "^0.2.2"
+      }
+    },
+    "combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dev": true,
+      "requires": {
+        "delayed-stream": "~1.0.0"
+      }
+    },
+    "commander": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
+      "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
+      "dev": true
+    },
+    "commitizen": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-4.1.2.tgz",
+      "integrity": "sha512-LBxTQKHbVgroMz9ohpm86N+GfJobonGyvDc3zBGdZazbwCLz2tqLa48Rf2TnAdKx7/06W1i1R3SXUt5QW97qVQ==",
+      "dev": true,
+      "requires": {
+        "cachedir": "2.2.0",
+        "cz-conventional-changelog": "3.2.0",
+        "dedent": "0.7.0",
+        "detect-indent": "6.0.0",
+        "find-node-modules": "2.0.0",
+        "find-root": "1.1.0",
+        "fs-extra": "8.1.0",
+        "glob": "7.1.4",
+        "inquirer": "6.5.0",
+        "is-utf8": "^0.2.1",
+        "lodash": "4.17.15",
+        "minimist": "1.2.5",
+        "strip-bom": "4.0.0",
+        "strip-json-comments": "3.0.1"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "7.1.4",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
+          "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
+          "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"
+          }
+        },
+        "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
+        }
+      }
+    },
+    "common-tags": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz",
+      "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==",
+      "dev": true
+    },
+    "commondir": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+      "dev": true
+    },
+    "compare-func": {
+      "version": "1.3.4",
+      "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.4.tgz",
+      "integrity": "sha512-sq2sWtrqKPkEXAC8tEJA1+BqAH9GbFkGBtUOqrUX57VSfwp8xyktctk+uLoRy5eccTdxzDcVIztlYDpKs3Jv1Q==",
+      "dev": true,
+      "requires": {
+        "array-ify": "^1.0.0",
+        "dot-prop": "^3.0.0"
+      }
+    },
+    "compare-versions": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz",
+      "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==",
+      "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
+    },
+    "compose-function": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz",
+      "integrity": "sha1-ntZ18TzFRQHTCVCkhv9qe6OrGF8=",
+      "dev": true,
+      "requires": {
+        "arity-n": "^1.0.4"
+      }
+    },
+    "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"
+          }
+        }
+      }
+    },
+    "compute-scroll-into-view": {
+      "version": "1.0.14",
+      "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.14.tgz",
+      "integrity": "sha512-mKDjINe3tc6hGelUMNDzuhorIUZ7kS7BwyY0r2wQd2HOH2tRuJykiC06iSEX8y1TuhNzvz4GcJnK16mM2J1NMQ=="
+    },
+    "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"
+      }
+    },
+    "confusing-browser-globals": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz",
+      "integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==",
+      "dev": true
+    },
+    "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
+    },
+    "contains-path": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz",
+      "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=",
+      "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
+    },
+    "conventional-changelog-angular": {
+      "version": "1.6.6",
+      "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-1.6.6.tgz",
+      "integrity": "sha512-suQnFSqCxRwyBxY68pYTsFkG0taIdinHLNEAX5ivtw8bCRnIgnpvcHmlR/yjUyZIrNPYAoXlY1WiEKWgSE4BNg==",
+      "dev": true,
+      "requires": {
+        "compare-func": "^1.3.1",
+        "q": "^1.5.1"
+      }
+    },
+    "conventional-changelog-conventionalcommits": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.2.1.tgz",
+      "integrity": "sha512-vC02KucnkNNap+foDKFm7BVUSDAXktXrUJqGszUuYnt6T0J2azsbYz/w9TDc3VsrW2v6JOtiQWVcgZnporHr4Q==",
+      "dev": true,
+      "requires": {
+        "compare-func": "^1.3.1",
+        "lodash": "^4.2.1",
+        "q": "^1.5.1"
+      }
+    },
+    "conventional-commit-types": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/conventional-commit-types/-/conventional-commit-types-3.0.0.tgz",
+      "integrity": "sha512-SmmCYnOniSsAa9GqWOeLqc179lfr5TRu5b4QFDkbsrJ5TZjPJx85wtOr3zn+1dbeNiXDKGPbZ72IKbPhLXh/Lg==",
+      "dev": true
+    },
+    "conventional-commits-parser": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.1.0.tgz",
+      "integrity": "sha512-RSo5S0WIwXZiRxUGTPuYFbqvrR4vpJ1BDdTlthFgvHt5kEdnd1+pdvwWphWn57/oIl4V72NMmOocFqqJ8mFFhA==",
+      "dev": true,
+      "requires": {
+        "JSONStream": "^1.0.4",
+        "is-text-path": "^1.0.1",
+        "lodash": "^4.17.15",
+        "meow": "^7.0.0",
+        "split2": "^2.0.0",
+        "through2": "^3.0.0",
+        "trim-off-newlines": "^1.0.0"
+      },
+      "dependencies": {
+        "meow": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npmjs.org/meow/-/meow-7.0.1.tgz",
+          "integrity": "sha512-tBKIQqVrAHqwit0vfuFPY3LlzJYkEOFyKa3bPgxzNl6q/RtN8KQ+ALYEASYuFayzSAsjlhXj/JZ10rH85Q6TUw==",
+          "dev": true,
+          "requires": {
+            "@types/minimist": "^1.2.0",
+            "arrify": "^2.0.1",
+            "camelcase": "^6.0.0",
+            "camelcase-keys": "^6.2.2",
+            "decamelize-keys": "^1.1.0",
+            "hard-rejection": "^2.1.0",
+            "minimist-options": "^4.0.2",
+            "normalize-package-data": "^2.5.0",
+            "read-pkg-up": "^7.0.1",
+            "redent": "^3.0.0",
+            "trim-newlines": "^3.0.0",
+            "type-fest": "^0.13.1",
+            "yargs-parser": "^18.1.3"
+          }
+        }
+      }
+    },
+    "convert-source-map": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
+      "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "~5.1.1"
+      }
+    },
+    "cookie": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
+      "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
+      "dev": true
+    },
+    "cookie-signature": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+      "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
+      "dev": true
+    },
+    "copy-concurrently": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
+      "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==",
+      "dev": true,
+      "requires": {
+        "aproba": "^1.1.1",
+        "fs-write-stream-atomic": "^1.0.8",
+        "iferr": "^0.1.5",
+        "mkdirp": "^0.5.1",
+        "rimraf": "^2.5.4",
+        "run-queue": "^1.0.0"
+      }
+    },
+    "copy-descriptor": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "dev": true
+    },
+    "copy-to-clipboard": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz",
+      "integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==",
+      "requires": {
+        "toggle-selection": "^1.0.6"
+      }
+    },
+    "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=="
+    },
+    "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-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
+    },
+    "core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+      "dev": true
+    },
+    "cosmiconfig": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
+      "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
+      "dev": true,
+      "requires": {
+        "import-fresh": "^2.0.0",
+        "is-directory": "^0.3.1",
+        "js-yaml": "^3.13.1",
+        "parse-json": "^4.0.0"
+      },
+      "dependencies": {
+        "import-fresh": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
+          "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
+          "dev": true,
+          "requires": {
+            "caller-path": "^2.0.0",
+            "resolve-from": "^3.0.0"
+          }
+        },
+        "parse-json": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+          "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+          "dev": true,
+          "requires": {
+            "error-ex": "^1.3.1",
+            "json-parse-better-errors": "^1.0.1"
+          }
+        },
+        "resolve-from": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+          "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+          "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"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+          "dev": true
+        }
+      }
+    },
+    "crypto-browserify": {
+      "version": "3.12.0",
+      "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+      "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+      "dev": true,
+      "requires": {
+        "browserify-cipher": "^1.0.0",
+        "browserify-sign": "^4.0.0",
+        "create-ecdh": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "create-hmac": "^1.1.0",
+        "diffie-hellman": "^5.0.0",
+        "inherits": "^2.0.1",
+        "pbkdf2": "^3.0.3",
+        "public-encrypt": "^4.0.0",
+        "randombytes": "^2.0.0",
+        "randomfill": "^1.0.3"
+      }
+    },
+    "css": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz",
+      "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.3",
+        "source-map": "^0.6.1",
+        "source-map-resolve": "^0.5.2",
+        "urix": "^0.1.0"
+      }
+    },
+    "css-blank-pseudo": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz",
+      "integrity": "sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.5"
+      }
+    },
+    "css-color-names": {
+      "version": "0.0.4",
+      "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
+      "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=",
+      "dev": true
+    },
+    "css-declaration-sorter": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz",
+      "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.1",
+        "timsort": "^0.3.0"
+      }
+    },
+    "css-has-pseudo": {
+      "version": "0.10.0",
+      "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz",
+      "integrity": "sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.6",
+        "postcss-selector-parser": "^5.0.0-rc.4"
+      },
+      "dependencies": {
+        "cssesc": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
+          "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==",
+          "dev": true
+        },
+        "postcss-selector-parser": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz",
+          "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==",
+          "dev": true,
+          "requires": {
+            "cssesc": "^2.0.0",
+            "indexes-of": "^1.0.1",
+            "uniq": "^1.0.1"
+          }
+        }
+      }
+    },
+    "css-loader": {
+      "version": "3.4.2",
+      "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.4.2.tgz",
+      "integrity": "sha512-jYq4zdZT0oS0Iykt+fqnzVLRIeiPWhka+7BqPn+oSIpWJAHak5tmB/WZrJ2a21JhCeFyNnnlroSl8c+MtVndzA==",
+      "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.23",
+        "postcss-modules-extract-imports": "^2.0.0",
+        "postcss-modules-local-by-default": "^3.0.2",
+        "postcss-modules-scope": "^2.1.1",
+        "postcss-modules-values": "^3.0.0",
+        "postcss-value-parser": "^4.0.2",
+        "schema-utils": "^2.6.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
+        }
+      }
+    },
+    "css-mediaquery": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/css-mediaquery/-/css-mediaquery-0.1.2.tgz",
+      "integrity": "sha1-aiw3NEkoYYYxxUvTPO3TAdoYvqA="
+    },
+    "css-prefers-color-scheme": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz",
+      "integrity": "sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.5"
+      }
+    },
+    "css-select": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz",
+      "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==",
+      "dev": true,
+      "requires": {
+        "boolbase": "^1.0.0",
+        "css-what": "^3.2.1",
+        "domutils": "^1.7.0",
+        "nth-check": "^1.0.2"
+      }
+    },
+    "css-select-base-adapter": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz",
+      "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==",
+      "dev": true
+    },
+    "css-tree": {
+      "version": "1.0.0-alpha.37",
+      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz",
+      "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==",
+      "dev": true,
+      "requires": {
+        "mdn-data": "2.0.4",
+        "source-map": "^0.6.1"
+      }
+    },
+    "css-what": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.3.0.tgz",
+      "integrity": "sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg==",
+      "dev": true
+    },
+    "css.escape": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
+      "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=",
+      "dev": true
+    },
+    "cssdb": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-4.4.0.tgz",
+      "integrity": "sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ==",
+      "dev": true
+    },
+    "cssesc": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+      "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+      "dev": true
+    },
+    "cssnano": {
+      "version": "4.1.10",
+      "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz",
+      "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==",
+      "dev": true,
+      "requires": {
+        "cosmiconfig": "^5.0.0",
+        "cssnano-preset-default": "^4.0.7",
+        "is-resolvable": "^1.0.0",
+        "postcss": "^7.0.0"
+      }
+    },
+    "cssnano-preset-default": {
+      "version": "4.0.7",
+      "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz",
+      "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==",
+      "dev": true,
+      "requires": {
+        "css-declaration-sorter": "^4.0.1",
+        "cssnano-util-raw-cache": "^4.0.1",
+        "postcss": "^7.0.0",
+        "postcss-calc": "^7.0.1",
+        "postcss-colormin": "^4.0.3",
+        "postcss-convert-values": "^4.0.1",
+        "postcss-discard-comments": "^4.0.2",
+        "postcss-discard-duplicates": "^4.0.2",
+        "postcss-discard-empty": "^4.0.1",
+        "postcss-discard-overridden": "^4.0.1",
+        "postcss-merge-longhand": "^4.0.11",
+        "postcss-merge-rules": "^4.0.3",
+        "postcss-minify-font-values": "^4.0.2",
+        "postcss-minify-gradients": "^4.0.2",
+        "postcss-minify-params": "^4.0.2",
+        "postcss-minify-selectors": "^4.0.2",
+        "postcss-normalize-charset": "^4.0.1",
+        "postcss-normalize-display-values": "^4.0.2",
+        "postcss-normalize-positions": "^4.0.2",
+        "postcss-normalize-repeat-style": "^4.0.2",
+        "postcss-normalize-string": "^4.0.2",
+        "postcss-normalize-timing-functions": "^4.0.2",
+        "postcss-normalize-unicode": "^4.0.1",
+        "postcss-normalize-url": "^4.0.1",
+        "postcss-normalize-whitespace": "^4.0.2",
+        "postcss-ordered-values": "^4.1.2",
+        "postcss-reduce-initial": "^4.0.3",
+        "postcss-reduce-transforms": "^4.0.2",
+        "postcss-svgo": "^4.0.2",
+        "postcss-unique-selectors": "^4.0.1"
+      }
+    },
+    "cssnano-util-get-arguments": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz",
+      "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=",
+      "dev": true
+    },
+    "cssnano-util-get-match": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz",
+      "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=",
+      "dev": true
+    },
+    "cssnano-util-raw-cache": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz",
+      "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.0"
+      }
+    },
+    "cssnano-util-same-parent": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz",
+      "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==",
+      "dev": true
+    },
+    "csso": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.3.tgz",
+      "integrity": "sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ==",
+      "dev": true,
+      "requires": {
+        "css-tree": "1.0.0-alpha.39"
+      },
+      "dependencies": {
+        "css-tree": {
+          "version": "1.0.0-alpha.39",
+          "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz",
+          "integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==",
+          "dev": true,
+          "requires": {
+            "mdn-data": "2.0.6",
+            "source-map": "^0.6.1"
+          }
+        },
+        "mdn-data": {
+          "version": "2.0.6",
+          "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz",
+          "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==",
+          "dev": true
+        }
+      }
+    },
+    "cssom": {
+      "version": "0.3.8",
+      "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
+      "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
+      "dev": true
+    },
+    "cssstyle": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz",
+      "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==",
+      "dev": true,
+      "requires": {
+        "cssom": "0.3.x"
+      }
+    },
+    "csstype": {
+      "version": "2.6.10",
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.10.tgz",
+      "integrity": "sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w==",
+      "dev": true
+    },
+    "currently-unhandled": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+      "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+      "dev": true,
+      "requires": {
+        "array-find-index": "^1.0.1"
+      }
+    },
+    "customize-cra": {
+      "version": "0.9.1",
+      "resolved": "https://registry.npmjs.org/customize-cra/-/customize-cra-0.9.1.tgz",
+      "integrity": "sha512-LISruJ6ak6u+HVQ2vPI+HE4inpPugB73KB9YIpE2J1TW5L1Vrjzm3l2Yupyy+1alJGwAd5GAb5Hfc9qmSUuHow==",
+      "dev": true,
+      "requires": {
+        "lodash.flow": "^3.5.0"
+      }
+    },
+    "cyclist": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
+      "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=",
+      "dev": true
+    },
+    "cz-conventional-changelog": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-3.2.0.tgz",
+      "integrity": "sha512-yAYxeGpVi27hqIilG1nh4A9Bnx4J3Ov+eXy4koL3drrR+IO9GaWPsKjik20ht608Asqi8TQPf0mczhEeyAtMzg==",
+      "dev": true,
+      "requires": {
+        "@commitlint/load": ">6.1.1",
+        "chalk": "^2.4.1",
+        "commitizen": "^4.0.3",
+        "conventional-commit-types": "^3.0.0",
+        "lodash.map": "^4.5.1",
+        "longest": "^2.0.1",
+        "word-wrap": "^1.0.3"
+      }
+    },
+    "d": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+      "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+      "dev": true,
+      "requires": {
+        "es5-ext": "^0.10.50",
+        "type": "^1.0.1"
+      }
+    },
+    "damerau-levenshtein": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz",
+      "integrity": "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==",
+      "dev": true
+    },
+    "dargs": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz",
+      "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==",
+      "dev": true
+    },
+    "dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "data-urls": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz",
+      "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==",
+      "dev": true,
+      "requires": {
+        "abab": "^2.0.0",
+        "whatwg-mimetype": "^2.2.0",
+        "whatwg-url": "^7.0.0"
+      },
+      "dependencies": {
+        "whatwg-url": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
+          "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
+          "dev": true,
+          "requires": {
+            "lodash.sortby": "^4.7.0",
+            "tr46": "^1.0.1",
+            "webidl-conversions": "^4.0.2"
+          }
+        }
+      }
+    },
+    "dayjs": {
+      "version": "1.8.28",
+      "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.28.tgz",
+      "integrity": "sha512-ccnYgKC0/hPSGXxj7Ju6AV/BP4HUkXC2u15mikXT5mX9YorEaoi1bEKOmAqdkJHN4EEkmAf97SpH66Try5Mbeg==",
+      "dev": true
+    },
+    "debug": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+      "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+      "requires": {
+        "ms": "2.0.0"
+      }
+    },
+    "decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "dev": true
+    },
+    "decamelize-keys": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz",
+      "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=",
+      "dev": true,
+      "requires": {
+        "decamelize": "^1.1.0",
+        "map-obj": "^1.0.0"
+      },
+      "dependencies": {
+        "map-obj": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+          "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+          "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
+    },
+    "dedent": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
+      "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=",
+      "dev": true
+    },
+    "deep-equal": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
+      "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
+      "dev": true,
+      "requires": {
+        "is-arguments": "^1.0.4",
+        "is-date-object": "^1.0.1",
+        "is-regex": "^1.0.4",
+        "object-is": "^1.0.1",
+        "object-keys": "^1.1.1",
+        "regexp.prototype.flags": "^1.2.0"
+      }
+    },
+    "deep-is": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+      "dev": true
+    },
+    "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"
+      },
+      "dependencies": {
+        "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"
+          }
+        },
+        "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"
+          }
+        },
+        "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"
+          }
+        }
+      }
+    },
+    "define-properties": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+      "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+      "dev": true,
+      "requires": {
+        "object-keys": "^1.0.12"
+      }
+    },
+    "define-property": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+      "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+      "dev": true,
+      "requires": {
+        "is-descriptor": "^1.0.2",
+        "isobject": "^3.0.1"
+      },
+      "dependencies": {
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "del": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz",
+      "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==",
+      "dev": true,
+      "requires": {
+        "@types/glob": "^7.1.1",
+        "globby": "^6.1.0",
+        "is-path-cwd": "^2.0.0",
+        "is-path-in-cwd": "^2.0.0",
+        "p-map": "^2.0.0",
+        "pify": "^4.0.1",
+        "rimraf": "^2.6.3"
+      },
+      "dependencies": {
+        "globby": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
+          "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
+          "dev": true,
+          "requires": {
+            "array-union": "^1.0.1",
+            "glob": "^7.0.3",
+            "object-assign": "^4.0.1",
+            "pify": "^2.0.0",
+            "pinkie-promise": "^2.0.0"
+          },
+          "dependencies": {
+            "pify": {
+              "version": "2.3.0",
+              "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+              "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+              "dev": true
+            }
+          }
+        },
+        "p-map": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
+          "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
+          "dev": true
+        },
+        "pify": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+          "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+          "dev": true
+        }
+      }
+    },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+      "dev": true
+    },
+    "depd": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+      "dev": true
+    },
+    "des.js": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
+      "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "destroy": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+      "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
+      "dev": true
+    },
+    "detect-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-indent": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz",
+      "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==",
+      "dev": true
+    },
+    "detect-newline": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz",
+      "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=",
+      "dev": true
+    },
+    "detect-node": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz",
+      "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==",
+      "dev": true
+    },
+    "detect-port-alt": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz",
+      "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==",
+      "dev": true,
+      "requires": {
+        "address": "^1.0.1",
+        "debug": "^2.6.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"
+          }
+        }
+      }
+    },
+    "diff-sequences": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz",
+      "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==",
+      "dev": true
+    },
+    "diffie-hellman": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+      "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "miller-rabin": "^4.0.0",
+        "randombytes": "^2.0.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "dir-glob": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz",
+      "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==",
+      "dev": true,
+      "requires": {
+        "arrify": "^1.0.1",
+        "path-type": "^3.0.0"
+      },
+      "dependencies": {
+        "arrify": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+          "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+          "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"
+      }
+    },
+    "doctrine": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+      "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+      "dev": true,
+      "requires": {
+        "esutils": "^2.0.2"
+      }
+    },
+    "dom-accessibility-api": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.3.0.tgz",
+      "integrity": "sha512-PzwHEmsRP3IGY4gv/Ug+rMeaTIyTJvadCb+ujYXYeIylbHJezIyNToe8KfEgHTCEYyC+/bUghYOGg8yMGlZ6vA==",
+      "dev": true
+    },
+    "dom-align": {
+      "version": "1.12.0",
+      "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.0.tgz",
+      "integrity": "sha512-YkoezQuhp3SLFGdOlr5xkqZ640iXrnHAwVYcDg8ZKRUtO7mSzSC2BA5V0VuyAwPSJA4CLIc6EDDJh4bEsD2+zA=="
+    },
+    "dom-converter": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz",
+      "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==",
+      "dev": true,
+      "requires": {
+        "utila": "~0.4"
+      }
+    },
+    "dom-serializer": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
+      "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
+      "dev": true,
+      "requires": {
+        "domelementtype": "^2.0.1",
+        "entities": "^2.0.0"
+      },
+      "dependencies": {
+        "domelementtype": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz",
+          "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==",
+          "dev": true
+        }
+      }
+    },
+    "dom-walk": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
+      "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==",
+      "dev": true
+    },
+    "domain-browser": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
+      "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
+      "dev": true
+    },
+    "domelementtype": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
+      "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
+      "dev": true
+    },
+    "domexception": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
+      "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
+      "dev": true,
+      "requires": {
+        "webidl-conversions": "^4.0.2"
+      }
+    },
+    "domhandler": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
+      "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
+      "dev": true,
+      "requires": {
+        "domelementtype": "1"
+      }
+    },
+    "domutils": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
+      "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
+      "dev": true,
+      "requires": {
+        "dom-serializer": "0",
+        "domelementtype": "1"
+      }
+    },
+    "dot-case": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.3.tgz",
+      "integrity": "sha512-7hwEmg6RiSQfm/GwPL4AAWXKy3YNNZA3oFv2Pdiey0mwkRCPZ9x6SZbkLcn8Ma5PYeVokzoD4Twv2n7LKp5WeA==",
+      "dev": true,
+      "requires": {
+        "no-case": "^3.0.3",
+        "tslib": "^1.10.0"
+      }
+    },
+    "dot-prop": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz",
+      "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=",
+      "dev": true,
+      "requires": {
+        "is-obj": "^1.0.0"
+      }
+    },
+    "dotenv": {
+      "version": "8.2.0",
+      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
+      "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
+      "dev": true
+    },
+    "dotenv-expand": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz",
+      "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==",
+      "dev": true
+    },
+    "duplexer": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
+      "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
+      "dev": true
+    },
+    "duplexify": {
+      "version": "3.7.1",
+      "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
+      "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.0.0",
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.0",
+        "stream-shift": "^1.0.0"
+      }
+    },
+    "ecc-jsbn": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+      "dev": true,
+      "requires": {
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.1.0"
+      }
+    },
+    "ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+      "dev": true
+    },
+    "ejs": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.3.tgz",
+      "integrity": "sha512-wmtrUGyfSC23GC/B1SMv2ogAUgbQEtDmTIhfqielrG5ExIM9TP4UoYdi90jLF1aTcsWCJNEO0UrgKzP0y3nTSg==",
+      "dev": true,
+      "requires": {
+        "jake": "^10.6.1"
+      }
+    },
+    "electron-to-chromium": {
+      "version": "1.3.465",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.465.tgz",
+      "integrity": "sha512-K/lUeT3NLAsJ5SHRDhK3/zd0tw7OUllYD8w+fTOXm6ljCPsp2qq+vMzxpLo8u1M27ZjZAjRbsA6rirvne2nAMQ==",
+      "dev": true
+    },
+    "elliptic": {
+      "version": "6.5.2",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz",
+      "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.4.0",
+        "brorand": "^1.0.1",
+        "hash.js": "^1.0.0",
+        "hmac-drbg": "^1.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true
+    },
+    "emojis-list": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+      "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+      "dev": true
+    },
+    "encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+      "dev": true
+    },
+    "encoding": {
+      "version": "0.1.12",
+      "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
+      "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
+      "requires": {
+        "iconv-lite": "~0.4.13"
+      }
+    },
+    "end-of-stream": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+      "dev": true,
+      "requires": {
+        "once": "^1.4.0"
+      }
+    },
+    "enhanced-resolve": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz",
+      "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "memory-fs": "^0.5.0",
+        "tapable": "^1.0.0"
+      },
+      "dependencies": {
+        "memory-fs": {
+          "version": "0.5.0",
+          "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz",
+          "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==",
+          "dev": true,
+          "requires": {
+            "errno": "^0.1.3",
+            "readable-stream": "^2.0.1"
+          }
+        }
+      }
+    },
+    "enquirer": {
+      "version": "2.3.5",
+      "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.5.tgz",
+      "integrity": "sha512-BNT1C08P9XD0vNg3J475yIUG+mVdp9T6towYFHUv897X0KoHBjB1shyrNmhmtHWKP17iSWgo7Gqh7BBuzLZMSA==",
+      "dev": true,
+      "requires": {
+        "ansi-colors": "^3.2.1"
+      }
+    },
+    "entities": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz",
+      "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==",
+      "dev": true
+    },
+    "errno": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
+      "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
+      "dev": true,
+      "requires": {
+        "prr": "~1.0.1"
+      }
+    },
+    "error-ex": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+      "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+      "dev": true,
+      "requires": {
+        "is-arrayish": "^0.2.1"
+      }
+    },
+    "es-abstract": {
+      "version": "1.17.5",
+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz",
+      "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==",
+      "dev": true,
+      "requires": {
+        "es-to-primitive": "^1.2.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1",
+        "is-callable": "^1.1.5",
+        "is-regex": "^1.0.5",
+        "object-inspect": "^1.7.0",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.0",
+        "string.prototype.trimleft": "^2.1.1",
+        "string.prototype.trimright": "^2.1.1"
+      }
+    },
+    "es-to-primitive": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+      "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+      "dev": true,
+      "requires": {
+        "is-callable": "^1.1.4",
+        "is-date-object": "^1.0.1",
+        "is-symbol": "^1.0.2"
+      }
+    },
+    "es5-ext": {
+      "version": "0.10.53",
+      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
+      "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
+      "dev": true,
+      "requires": {
+        "es6-iterator": "~2.0.3",
+        "es6-symbol": "~3.1.3",
+        "next-tick": "~1.0.0"
+      }
+    },
+    "es6-iterator": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+      "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+      "dev": true,
+      "requires": {
+        "d": "1",
+        "es5-ext": "^0.10.35",
+        "es6-symbol": "^3.1.1"
+      }
+    },
+    "es6-symbol": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
+      "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
+      "dev": true,
+      "requires": {
+        "d": "^1.0.1",
+        "ext": "^1.1.2"
+      }
+    },
+    "escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+      "dev": true
+    },
+    "escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+      "dev": true
+    },
+    "escodegen": {
+      "version": "1.14.2",
+      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.2.tgz",
+      "integrity": "sha512-InuOIiKk8wwuOFg6x9BQXbzjrQhtyXh46K9bqVTPzSo2FnyMBaYGBMC6PhQy7yxxil9vIedFBweQBMK74/7o8A==",
+      "dev": true,
+      "requires": {
+        "esprima": "^4.0.1",
+        "estraverse": "^4.2.0",
+        "esutils": "^2.0.2",
+        "optionator": "^0.8.1",
+        "source-map": "~0.6.1"
+      }
+    },
+    "eslint": {
+      "version": "6.8.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz",
+      "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.0.0",
+        "ajv": "^6.10.0",
+        "chalk": "^2.1.0",
+        "cross-spawn": "^6.0.5",
+        "debug": "^4.0.1",
+        "doctrine": "^3.0.0",
+        "eslint-scope": "^5.0.0",
+        "eslint-utils": "^1.4.3",
+        "eslint-visitor-keys": "^1.1.0",
+        "espree": "^6.1.2",
+        "esquery": "^1.0.1",
+        "esutils": "^2.0.2",
+        "file-entry-cache": "^5.0.1",
+        "functional-red-black-tree": "^1.0.1",
+        "glob-parent": "^5.0.0",
+        "globals": "^12.1.0",
+        "ignore": "^4.0.6",
+        "import-fresh": "^3.0.0",
+        "imurmurhash": "^0.1.4",
+        "inquirer": "^7.0.0",
+        "is-glob": "^4.0.0",
+        "js-yaml": "^3.13.1",
+        "json-stable-stringify-without-jsonify": "^1.0.1",
+        "levn": "^0.3.0",
+        "lodash": "^4.17.14",
+        "minimatch": "^3.0.4",
+        "mkdirp": "^0.5.1",
+        "natural-compare": "^1.4.0",
+        "optionator": "^0.8.3",
+        "progress": "^2.0.0",
+        "regexpp": "^2.0.1",
+        "semver": "^6.1.2",
+        "strip-ansi": "^5.2.0",
+        "strip-json-comments": "^3.0.1",
+        "table": "^5.2.3",
+        "text-table": "^0.2.0",
+        "v8-compile-cache": "^2.0.3"
+      },
+      "dependencies": {
+        "ansi-escapes": {
+          "version": "4.3.1",
+          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
+          "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==",
+          "dev": true,
+          "requires": {
+            "type-fest": "^0.11.0"
+          }
+        },
+        "ansi-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"
+          }
+        },
+        "cli-cursor": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+          "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+          "dev": true,
+          "requires": {
+            "restore-cursor": "^3.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "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"
+          }
+        },
+        "figures": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
+          "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
+          "dev": true,
+          "requires": {
+            "escape-string-regexp": "^1.0.5"
+          }
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "inquirer": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz",
+          "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==",
+          "dev": true,
+          "requires": {
+            "ansi-escapes": "^4.2.1",
+            "chalk": "^3.0.0",
+            "cli-cursor": "^3.1.0",
+            "cli-width": "^2.0.0",
+            "external-editor": "^3.0.3",
+            "figures": "^3.0.0",
+            "lodash": "^4.17.15",
+            "mute-stream": "0.0.8",
+            "run-async": "^2.4.0",
+            "rxjs": "^6.5.3",
+            "string-width": "^4.1.0",
+            "strip-ansi": "^6.0.0",
+            "through": "^2.3.6"
+          },
+          "dependencies": {
+            "chalk": {
+              "version": "3.0.0",
+              "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+              "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+              "dev": true,
+              "requires": {
+                "ansi-styles": "^4.1.0",
+                "supports-color": "^7.1.0"
+              }
+            },
+            "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"
+              }
+            }
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+          "dev": true
+        },
+        "mimic-fn": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+          "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+          "dev": true
+        },
+        "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
+        },
+        "mute-stream": {
+          "version": "0.0.8",
+          "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+          "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
+          "dev": true
+        },
+        "onetime": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
+          "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
+          "dev": true,
+          "requires": {
+            "mimic-fn": "^2.1.0"
+          }
+        },
+        "restore-cursor": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+          "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+          "dev": true,
+          "requires": {
+            "onetime": "^5.1.0",
+            "signal-exit": "^3.0.2"
+          }
+        },
+        "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"
+          },
+          "dependencies": {
+            "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"
+              }
+            }
+          }
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        },
+        "type-fest": {
+          "version": "0.11.0",
+          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
+          "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==",
+          "dev": true
+        }
+      }
+    },
+    "eslint-config-prettier": {
+      "version": "6.11.0",
+      "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz",
+      "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==",
+      "dev": true,
+      "requires": {
+        "get-stdin": "^6.0.0"
+      },
+      "dependencies": {
+        "get-stdin": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz",
+          "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==",
+          "dev": true
+        }
+      }
+    },
+    "eslint-config-react-app": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-5.2.1.tgz",
+      "integrity": "sha512-pGIZ8t0mFLcV+6ZirRgYK6RVqUIKRIi9MmgzUEmrIknsn3AdO0I32asO86dJgloHq+9ZPl8UIg8mYrvgP5u2wQ==",
+      "dev": true,
+      "requires": {
+        "confusing-browser-globals": "^1.0.9"
+      }
+    },
+    "eslint-import-resolver-node": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz",
+      "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==",
+      "dev": true,
+      "requires": {
+        "debug": "^2.6.9",
+        "resolve": "^1.13.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"
+          }
+        }
+      }
+    },
+    "eslint-loader": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-3.0.3.tgz",
+      "integrity": "sha512-+YRqB95PnNvxNp1HEjQmvf9KNvCin5HXYYseOXVC2U0KEcw4IkQ2IQEBG46j7+gW39bMzeu0GsUhVbBY3Votpw==",
+      "dev": true,
+      "requires": {
+        "fs-extra": "^8.1.0",
+        "loader-fs-cache": "^1.0.2",
+        "loader-utils": "^1.2.3",
+        "object-hash": "^2.0.1",
+        "schema-utils": "^2.6.1"
+      }
+    },
+    "eslint-module-utils": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz",
+      "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==",
+      "dev": true,
+      "requires": {
+        "debug": "^2.6.9",
+        "pkg-dir": "^2.0.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "find-up": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+          "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+          "dev": true,
+          "requires": {
+            "locate-path": "^2.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+          "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+          "dev": true,
+          "requires": {
+            "p-locate": "^2.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "p-limit": {
+          "version": "1.3.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+          "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+          "dev": true,
+          "requires": {
+            "p-try": "^1.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+          "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+          "dev": true,
+          "requires": {
+            "p-limit": "^1.1.0"
+          }
+        },
+        "p-try": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+          "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+          "dev": true
+        },
+        "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
+        },
+        "pkg-dir": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
+          "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
+          "dev": true,
+          "requires": {
+            "find-up": "^2.1.0"
+          }
+        }
+      }
+    },
+    "eslint-plugin-flowtype": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-4.6.0.tgz",
+      "integrity": "sha512-W5hLjpFfZyZsXfo5anlu7HM970JBDqbEshAJUkeczP6BFCIfJXuiIBQXyberLRtOStT0OGPF8efeTbxlHk4LpQ==",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.17.15"
+      }
+    },
+    "eslint-plugin-import": {
+      "version": "2.20.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.0.tgz",
+      "integrity": "sha512-NK42oA0mUc8Ngn4kONOPsPB1XhbUvNHqF+g307dPV28aknPoiNnKLFd9em4nkswwepdF5ouieqv5Th/63U7YJQ==",
+      "dev": true,
+      "requires": {
+        "array-includes": "^3.0.3",
+        "array.prototype.flat": "^1.2.1",
+        "contains-path": "^0.1.0",
+        "debug": "^2.6.9",
+        "doctrine": "1.5.0",
+        "eslint-import-resolver-node": "^0.3.2",
+        "eslint-module-utils": "^2.4.1",
+        "has": "^1.0.3",
+        "minimatch": "^3.0.4",
+        "object.values": "^1.1.0",
+        "read-pkg-up": "^2.0.0",
+        "resolve": "^1.12.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"
+          }
+        },
+        "doctrine": {
+          "version": "1.5.0",
+          "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+          "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "isarray": "^1.0.0"
+          }
+        },
+        "find-up": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+          "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+          "dev": true,
+          "requires": {
+            "locate-path": "^2.0.0"
+          }
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "load-json-file": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+          "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "^4.1.2",
+            "parse-json": "^2.2.0",
+            "pify": "^2.0.0",
+            "strip-bom": "^3.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+          "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+          "dev": true,
+          "requires": {
+            "p-locate": "^2.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "p-limit": {
+          "version": "1.3.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+          "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+          "dev": true,
+          "requires": {
+            "p-try": "^1.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+          "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+          "dev": true,
+          "requires": {
+            "p-limit": "^1.1.0"
+          }
+        },
+        "p-try": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+          "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+          "dev": true
+        },
+        "parse-json": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+          "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+          "dev": true,
+          "requires": {
+            "error-ex": "^1.2.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
+        },
+        "path-type": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
+          "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
+          "dev": true,
+          "requires": {
+            "pify": "^2.0.0"
+          }
+        },
+        "pify": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+          "dev": true
+        },
+        "read-pkg": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
+          "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
+          "dev": true,
+          "requires": {
+            "load-json-file": "^2.0.0",
+            "normalize-package-data": "^2.3.2",
+            "path-type": "^2.0.0"
+          }
+        },
+        "read-pkg-up": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
+          "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
+          "dev": true,
+          "requires": {
+            "find-up": "^2.0.0",
+            "read-pkg": "^2.0.0"
+          }
+        }
+      }
+    },
+    "eslint-plugin-jsx-a11y": {
+      "version": "6.2.3",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz",
+      "integrity": "sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg==",
+      "dev": true,
+      "requires": {
+        "@babel/runtime": "^7.4.5",
+        "aria-query": "^3.0.0",
+        "array-includes": "^3.0.3",
+        "ast-types-flow": "^0.0.7",
+        "axobject-query": "^2.0.2",
+        "damerau-levenshtein": "^1.0.4",
+        "emoji-regex": "^7.0.2",
+        "has": "^1.0.3",
+        "jsx-ast-utils": "^2.2.1"
+      },
+      "dependencies": {
+        "aria-query": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz",
+          "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=",
+          "dev": true,
+          "requires": {
+            "ast-types-flow": "0.0.7",
+            "commander": "^2.11.0"
+          }
+        },
+        "commander": {
+          "version": "2.20.3",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+          "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+          "dev": true
+        },
+        "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
+        }
+      }
+    },
+    "eslint-plugin-prettier": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.3.tgz",
+      "integrity": "sha512-+HG5jmu/dN3ZV3T6eCD7a4BlAySdN7mLIbJYo0z1cFQuI+r2DiTJEFeF68ots93PsnrMxbzIZ2S/ieX+mkrBeQ==",
+      "dev": true,
+      "requires": {
+        "prettier-linter-helpers": "^1.0.0"
+      }
+    },
+    "eslint-plugin-react": {
+      "version": "7.20.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.0.tgz",
+      "integrity": "sha512-rqe1abd0vxMjmbPngo4NaYxTcR3Y4Hrmc/jg4T+sYz63yqlmJRknpEQfmWY+eDWPuMmix6iUIK+mv0zExjeLgA==",
+      "dev": true,
+      "requires": {
+        "array-includes": "^3.1.1",
+        "doctrine": "^2.1.0",
+        "has": "^1.0.3",
+        "jsx-ast-utils": "^2.2.3",
+        "object.entries": "^1.1.1",
+        "object.fromentries": "^2.0.2",
+        "object.values": "^1.1.1",
+        "prop-types": "^15.7.2",
+        "resolve": "^1.15.1",
+        "string.prototype.matchall": "^4.0.2",
+        "xregexp": "^4.3.0"
+      },
+      "dependencies": {
+        "doctrine": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+          "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2"
+          }
+        }
+      }
+    },
+    "eslint-plugin-react-hooks": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.0.4.tgz",
+      "integrity": "sha512-equAdEIsUETLFNCmmCkiCGq6rkSK5MoJhXFPFYeUebcjKgBmWWcgVOqZyQC8Bv1BwVCnTq9tBxgJFgAJTWoJtA==",
+      "dev": true
+    },
+    "eslint-scope": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz",
+      "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==",
+      "dev": true,
+      "requires": {
+        "esrecurse": "^4.1.0",
+        "estraverse": "^4.1.1"
+      }
+    },
+    "eslint-utils": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
+      "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
+      "dev": true,
+      "requires": {
+        "eslint-visitor-keys": "^1.1.0"
+      }
+    },
+    "eslint-visitor-keys": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.2.0.tgz",
+      "integrity": "sha512-WFb4ihckKil6hu3Dp798xdzSfddwKKU3+nGniKF6HfeW6OLd2OUDEPP7TcHtB5+QXOKg2s6B2DaMPE1Nn/kxKQ==",
+      "dev": true
+    },
+    "espree": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz",
+      "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==",
+      "dev": true,
+      "requires": {
+        "acorn": "^7.1.1",
+        "acorn-jsx": "^5.2.0",
+        "eslint-visitor-keys": "^1.1.0"
+      }
+    },
+    "esprima": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+      "dev": true
+    },
+    "esquery": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz",
+      "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==",
+      "dev": true,
+      "requires": {
+        "estraverse": "^5.1.0"
+      },
+      "dependencies": {
+        "estraverse": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz",
+          "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==",
+          "dev": true
+        }
+      }
+    },
+    "esrecurse": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+      "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+      "dev": true,
+      "requires": {
+        "estraverse": "^4.1.0"
+      }
+    },
+    "estraverse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+      "dev": true
+    },
+    "esutils": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+      "dev": true
+    },
+    "etag": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+      "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+      "dev": true
+    },
+    "eventemitter3": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz",
+      "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==",
+      "dev": true
+    },
+    "events": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz",
+      "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==",
+      "dev": true
+    },
+    "eventsource": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz",
+      "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==",
+      "dev": true,
+      "requires": {
+        "original": "^1.0.0"
+      }
+    },
+    "evp_bytestokey": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+      "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+      "dev": true,
+      "requires": {
+        "md5.js": "^1.3.4",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "exec-sh": {
+      "version": "0.3.4",
+      "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz",
+      "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==",
+      "dev": true
+    },
+    "execa": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.2.tgz",
+      "integrity": "sha512-QI2zLa6CjGWdiQsmSkZoGtDx2N+cQIGb3yNolGTdjSQzydzLgYYf8LRuagp7S7fPimjcrzUDSUFd/MgzELMi4Q==",
+      "dev": true,
+      "requires": {
+        "cross-spawn": "^7.0.0",
+        "get-stream": "^5.0.0",
+        "human-signals": "^1.1.1",
+        "is-stream": "^2.0.0",
+        "merge-stream": "^2.0.0",
+        "npm-run-path": "^4.0.0",
+        "onetime": "^5.1.0",
+        "signal-exit": "^3.0.2",
+        "strip-final-newline": "^2.0.0"
+      },
+      "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"
+          }
+        },
+        "is-stream": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+          "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+          "dev": true
+        },
+        "mimic-fn": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+          "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+          "dev": true
+        },
+        "onetime": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
+          "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
+          "dev": true,
+          "requires": {
+            "mimic-fn": "^2.1.0"
+          }
+        },
+        "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"
+          }
+        }
+      }
+    },
+    "execall": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz",
+      "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==",
+      "dev": true,
+      "requires": {
+        "clone-regexp": "^2.1.0"
+      }
+    },
+    "exit": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+      "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
+      "dev": true
+    },
+    "expand-brackets": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+      "dev": true,
+      "requires": {
+        "debug": "^2.3.3",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "posix-character-classes": "^0.1.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "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"
+      }
+    },
+    "expect": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz",
+      "integrity": "sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^24.9.0",
+        "ansi-styles": "^3.2.0",
+        "jest-get-type": "^24.9.0",
+        "jest-matcher-utils": "^24.9.0",
+        "jest-message-util": "^24.9.0",
+        "jest-regex-util": "^24.9.0"
+      }
+    },
+    "express": {
+      "version": "4.17.1",
+      "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
+      "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
+      "dev": true,
+      "requires": {
+        "accepts": "~1.3.7",
+        "array-flatten": "1.1.1",
+        "body-parser": "1.19.0",
+        "content-disposition": "0.5.3",
+        "content-type": "~1.0.4",
+        "cookie": "0.4.0",
+        "cookie-signature": "1.0.6",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "finalhandler": "~1.1.2",
+        "fresh": "0.5.2",
+        "merge-descriptors": "1.0.1",
+        "methods": "~1.1.2",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.3",
+        "path-to-regexp": "0.1.7",
+        "proxy-addr": "~2.0.5",
+        "qs": "6.7.0",
+        "range-parser": "~1.2.1",
+        "safe-buffer": "5.1.2",
+        "send": "0.17.1",
+        "serve-static": "1.14.1",
+        "setprototypeof": "1.1.1",
+        "statuses": "~1.5.0",
+        "type-is": "~1.6.18",
+        "utils-merge": "1.0.1",
+        "vary": "~1.1.2"
+      },
+      "dependencies": {
+        "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"
+          }
+        },
+        "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
+        },
+        "qs": {
+          "version": "6.7.0",
+          "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+          "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+          "dev": true
+        }
+      }
+    },
+    "ext": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
+      "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
+      "dev": true,
+      "requires": {
+        "type": "^2.0.0"
+      },
+      "dependencies": {
+        "type": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz",
+          "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==",
+          "dev": true
+        }
+      }
+    },
+    "extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+      "dev": true
+    },
+    "extend-shallow": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+      "dev": true,
+      "requires": {
+        "assign-symbols": "^1.0.0",
+        "is-extendable": "^1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "^2.0.4"
+          }
+        }
+      }
+    },
+    "external-editor": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
+      "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
+      "dev": true,
+      "requires": {
+        "chardet": "^0.7.0",
+        "iconv-lite": "^0.4.24",
+        "tmp": "^0.0.33"
+      }
+    },
+    "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"
+          }
+        }
+      }
+    },
+    "extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+      "dev": true
+    },
+    "fast-deep-equal": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+      "dev": true
+    },
+    "fast-diff": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
+      "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
+      "dev": true
+    },
+    "fast-glob": {
+      "version": "2.2.7",
+      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz",
+      "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==",
+      "dev": true,
+      "requires": {
+        "@mrmlnc/readdir-enhanced": "^2.2.1",
+        "@nodelib/fs.stat": "^1.1.2",
+        "glob-parent": "^3.1.0",
+        "is-glob": "^4.0.0",
+        "merge2": "^1.2.3",
+        "micromatch": "^3.1.10"
+      },
+      "dependencies": {
+        "glob-parent": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+          "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+          "dev": true,
+          "requires": {
+            "is-glob": "^3.1.0",
+            "path-dirname": "^1.0.0"
+          },
+          "dependencies": {
+            "is-glob": {
+              "version": "3.1.0",
+              "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+              "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+              "dev": true,
+              "requires": {
+                "is-extglob": "^2.1.0"
+              }
+            }
+          }
+        }
+      }
+    },
+    "fast-json-stable-stringify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+      "dev": true
+    },
+    "fast-levenshtein": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+      "dev": true
+    },
+    "fastq": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz",
+      "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==",
+      "dev": true,
+      "requires": {
+        "reusify": "^1.0.4"
+      }
+    },
+    "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"
+      }
+    },
+    "fb-watchman": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz",
+      "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==",
+      "dev": true,
+      "requires": {
+        "bser": "2.1.1"
+      }
+    },
+    "figgy-pudding": {
+      "version": "3.5.2",
+      "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
+      "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==",
+      "dev": true
+    },
+    "figures": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+      "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+      "dev": true,
+      "requires": {
+        "escape-string-regexp": "^1.0.5"
+      }
+    },
+    "file-entry-cache": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
+      "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
+      "dev": true,
+      "requires": {
+        "flat-cache": "^2.0.1"
+      }
+    },
+    "file-loader": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-4.3.0.tgz",
+      "integrity": "sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.2.3",
+        "schema-utils": "^2.5.0"
+      }
+    },
+    "file-uri-to-path": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+      "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+      "dev": true,
+      "optional": true
+    },
+    "filelist": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.1.tgz",
+      "integrity": "sha512-8zSK6Nu0DQIC08mUC46sWGXi+q3GGpKydAG36k+JDba6VRpkevvOWUW5a/PhShij4+vHT9M+ghgG7eM+a9JDUQ==",
+      "dev": true,
+      "requires": {
+        "minimatch": "^3.0.4"
+      }
+    },
+    "filesize": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.0.1.tgz",
+      "integrity": "sha512-u4AYWPgbI5GBhs6id1KdImZWn5yfyFrrQ8OWZdN7ZMfA8Bf4HcO0BGo9bmUIEV8yrp8I1xVfJ/dn90GtFNNJcg==",
+      "dev": true
+    },
+    "fill-range": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+      "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^2.0.1",
+        "is-number": "^3.0.0",
+        "repeat-string": "^1.6.1",
+        "to-regex-range": "^2.1.0"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "finalhandler": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+      "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.3",
+        "statuses": "~1.5.0",
+        "unpipe": "~1.0.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "find-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"
+      },
+      "dependencies": {
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^3.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "p-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
+        },
+        "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"
+          }
+        }
+      }
+    },
+    "find-node-modules": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/find-node-modules/-/find-node-modules-2.0.0.tgz",
+      "integrity": "sha512-8MWIBRgJi/WpjjfVXumjPKCtmQ10B+fjx6zmSA+770GMJirLhWIzg8l763rhjl9xaeaHbnxPNRQKq2mgMhr+aw==",
+      "dev": true,
+      "requires": {
+        "findup-sync": "^3.0.0",
+        "merge": "^1.2.1"
+      }
+    },
+    "find-root": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
+      "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
+      "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"
+      }
+    },
+    "find-versions": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz",
+      "integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==",
+      "dev": true,
+      "requires": {
+        "semver-regex": "^2.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-cache": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
+      "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
+      "dev": true,
+      "requires": {
+        "flatted": "^2.0.0",
+        "rimraf": "2.6.3",
+        "write": "1.0.3"
+      },
+      "dependencies": {
+        "rimraf": {
+          "version": "2.6.3",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+          "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+          "dev": true,
+          "requires": {
+            "glob": "^7.1.3"
+          }
+        }
+      }
+    },
+    "flatted": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
+      "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
+      "dev": true
+    },
+    "flatten": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz",
+      "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==",
+      "dev": true
+    },
+    "flush-write-stream": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz",
+      "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.3.6"
+      }
+    },
+    "follow-redirects": {
+      "version": "1.5.10",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
+      "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
+      "requires": {
+        "debug": "=3.1.0"
+      }
+    },
+    "for-in": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+      "dev": true
+    },
+    "for-own": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
+      "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
+      "dev": true,
+      "requires": {
+        "for-in": "^1.0.1"
+      }
+    },
+    "forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+      "dev": true
+    },
+    "fork-ts-checker-webpack-plugin": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-3.1.1.tgz",
+      "integrity": "sha512-DuVkPNrM12jR41KM2e+N+styka0EgLkTnXmNcXdgOM37vtGeY+oCBK/Jx0hzSeEU6memFCtWb4htrHPMDfwwUQ==",
+      "dev": true,
+      "requires": {
+        "babel-code-frame": "^6.22.0",
+        "chalk": "^2.4.1",
+        "chokidar": "^3.3.0",
+        "micromatch": "^3.1.10",
+        "minimatch": "^3.0.4",
+        "semver": "^5.6.0",
+        "tapable": "^1.0.0",
+        "worker-rpc": "^0.1.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+          "dev": true
+        }
+      }
+    },
+    "form-data": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+      "dev": true,
+      "requires": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.6",
+        "mime-types": "^2.1.12"
+      }
+    },
+    "forwarded": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+      "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
+      "dev": true
+    },
+    "fragment-cache": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+      "dev": true,
+      "requires": {
+        "map-cache": "^0.2.2"
+      }
+    },
+    "fresh": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+      "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+      "dev": true
+    },
+    "from2": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+      "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.0"
+      }
+    },
+    "fs-extra": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+      "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
+      }
+    },
+    "fs-minipass": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+      "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+      "dev": true,
+      "requires": {
+        "minipass": "^3.0.0"
+      }
+    },
+    "fs-write-stream-atomic": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
+      "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "iferr": "^0.1.5",
+        "imurmurhash": "^0.1.4",
+        "readable-stream": "1 || 2"
+      }
+    },
+    "fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "dev": true
+    },
+    "fsevents": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz",
+      "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==",
+      "dev": true,
+      "optional": true
+    },
+    "function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+      "dev": true
+    },
+    "functional-red-black-tree": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+      "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+      "dev": true
+    },
+    "gensync": {
+      "version": "1.0.0-beta.1",
+      "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz",
+      "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==",
+      "dev": true
+    },
+    "get-caller-file": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+      "dev": true
+    },
+    "get-own-enumerable-property-symbols": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz",
+      "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==",
+      "dev": true
+    },
+    "get-stdin": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz",
+      "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==",
+      "dev": true
+    },
+    "get-stream": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz",
+      "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==",
+      "dev": true,
+      "requires": {
+        "pump": "^3.0.0"
+      }
+    },
+    "get-value": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+      "dev": true
+    },
+    "getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "git-raw-commits": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.7.tgz",
+      "integrity": "sha512-SkwrTqrDxw8y0G1uGJ9Zw13F7qu3LF8V4BifyDeiJCxSnjRGZD9SaoMiMqUvvXMXh6S3sOQ1DsBN7L2fMUZW/g==",
+      "dev": true,
+      "requires": {
+        "dargs": "^7.0.0",
+        "lodash.template": "^4.0.2",
+        "meow": "^7.0.0",
+        "split2": "^2.0.0",
+        "through2": "^3.0.0"
+      },
+      "dependencies": {
+        "meow": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npmjs.org/meow/-/meow-7.0.1.tgz",
+          "integrity": "sha512-tBKIQqVrAHqwit0vfuFPY3LlzJYkEOFyKa3bPgxzNl6q/RtN8KQ+ALYEASYuFayzSAsjlhXj/JZ10rH85Q6TUw==",
+          "dev": true,
+          "requires": {
+            "@types/minimist": "^1.2.0",
+            "arrify": "^2.0.1",
+            "camelcase": "^6.0.0",
+            "camelcase-keys": "^6.2.2",
+            "decamelize-keys": "^1.1.0",
+            "hard-rejection": "^2.1.0",
+            "minimist-options": "^4.0.2",
+            "normalize-package-data": "^2.5.0",
+            "read-pkg-up": "^7.0.1",
+            "redent": "^3.0.0",
+            "trim-newlines": "^3.0.0",
+            "type-fest": "^0.13.1",
+            "yargs-parser": "^18.1.3"
+          }
+        }
+      }
+    },
+    "glob": {
+      "version": "7.1.6",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+      "dev": true,
+      "requires": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      }
+    },
+    "glob-parent": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
+      "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
+      "dev": true,
+      "requires": {
+        "is-glob": "^4.0.1"
+      }
+    },
+    "glob-to-regexp": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz",
+      "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=",
+      "dev": true
+    },
+    "global": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz",
+      "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==",
+      "dev": true,
+      "requires": {
+        "min-document": "^2.19.0",
+        "process": "^0.11.10"
+      }
+    },
+    "global-dirs": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
+      "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
+      "dev": true,
+      "requires": {
+        "ini": "^1.3.4"
+      }
+    },
+    "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"
+      }
+    },
+    "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": "12.4.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
+      "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
+      "dev": true,
+      "requires": {
+        "type-fest": "^0.8.1"
+      },
+      "dependencies": {
+        "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
+        }
+      }
+    },
+    "globby": {
+      "version": "8.0.2",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.2.tgz",
+      "integrity": "sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w==",
+      "dev": true,
+      "requires": {
+        "array-union": "^1.0.1",
+        "dir-glob": "2.0.0",
+        "fast-glob": "^2.0.2",
+        "glob": "^7.1.2",
+        "ignore": "^3.3.5",
+        "pify": "^3.0.0",
+        "slash": "^1.0.0"
+      },
+      "dependencies": {
+        "ignore": {
+          "version": "3.3.10",
+          "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz",
+          "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==",
+          "dev": true
+        },
+        "slash": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
+          "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
+          "dev": true
+        }
+      }
+    },
+    "globjoin": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz",
+      "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=",
+      "dev": true
+    },
+    "gonzales-pe": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz",
+      "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==",
+      "dev": true,
+      "requires": {
+        "minimist": "^1.2.5"
+      }
+    },
+    "graceful-fs": {
+      "version": "4.2.4",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
+      "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
+      "dev": true
+    },
+    "growly": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
+      "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
+      "dev": true
+    },
+    "gud": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz",
+      "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw=="
+    },
+    "gzip-size": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz",
+      "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==",
+      "dev": true,
+      "requires": {
+        "duplexer": "^0.1.1",
+        "pify": "^4.0.1"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+          "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+          "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
+    },
+    "har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+      "dev": true
+    },
+    "har-validator": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
+      "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
+      "dev": true,
+      "requires": {
+        "ajv": "^6.5.5",
+        "har-schema": "^2.0.0"
+      }
+    },
+    "hard-rejection": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
+      "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==",
+      "dev": true
+    },
+    "harmony-reflect": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.1.tgz",
+      "integrity": "sha512-WJTeyp0JzGtHcuMsi7rw2VwtkvLa+JyfEKJCFyfcS0+CDkjQ5lHPu7zEhFZP+PDSRrEgXa5Ah0l1MbgbE41XjA==",
+      "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-ansi": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+      "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+      "dev": true,
+      "requires": {
+        "ansi-regex": "^2.0.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+          "dev": true
+        }
+      }
+    },
+    "has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+      "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": {
+        "kind-of": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "hash-base": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
+      "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.4",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.2.1",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+          "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+          "dev": true
+        }
+      }
+    },
+    "hash.js": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+      "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+      "requires": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.1"
+      }
+    },
+    "he": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+      "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+      "dev": true
+    },
+    "hex-color-regex": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
+      "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==",
+      "dev": true
+    },
+    "history": {
+      "version": "4.10.1",
+      "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
+      "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==",
+      "requires": {
+        "@babel/runtime": "^7.1.2",
+        "loose-envify": "^1.2.0",
+        "resolve-pathname": "^3.0.0",
+        "tiny-invariant": "^1.0.2",
+        "tiny-warning": "^1.0.0",
+        "value-equal": "^1.0.1"
+      }
+    },
+    "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"
+      }
+    },
+    "hosted-git-info": {
+      "version": "2.8.8",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
+      "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
+      "dev": true
+    },
+    "hpack.js": {
+      "version": "2.1.6",
+      "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
+      "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "obuf": "^1.0.0",
+        "readable-stream": "^2.0.1",
+        "wbuf": "^1.1.0"
+      }
+    },
+    "hsl-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz",
+      "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=",
+      "dev": true
+    },
+    "hsla-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz",
+      "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=",
+      "dev": true
+    },
+    "html-comment-regex": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz",
+      "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==",
+      "dev": true
+    },
+    "html-encoding-sniffer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
+      "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
+      "dev": true,
+      "requires": {
+        "whatwg-encoding": "^1.0.1"
+      }
+    },
+    "html-entities": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz",
+      "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==",
+      "dev": true
+    },
+    "html-escaper": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+      "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+      "dev": true
+    },
+    "html-minifier-terser": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz",
+      "integrity": "sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg==",
+      "dev": true,
+      "requires": {
+        "camel-case": "^4.1.1",
+        "clean-css": "^4.2.3",
+        "commander": "^4.1.1",
+        "he": "^1.2.0",
+        "param-case": "^3.0.3",
+        "relateurl": "^0.2.7",
+        "terser": "^4.6.3"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+          "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+          "dev": true
+        }
+      }
+    },
+    "html-tags": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz",
+      "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==",
+      "dev": true
+    },
+    "html-webpack-plugin": {
+      "version": "4.0.0-beta.11",
+      "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.11.tgz",
+      "integrity": "sha512-4Xzepf0qWxf8CGg7/WQM5qBB2Lc/NFI7MhU59eUDTkuQp3skZczH4UA1d6oQyDEIoMDgERVhRyTdtUPZ5s5HBg==",
+      "dev": true,
+      "requires": {
+        "html-minifier-terser": "^5.0.1",
+        "loader-utils": "^1.2.3",
+        "lodash": "^4.17.15",
+        "pretty-error": "^2.1.1",
+        "tapable": "^1.1.3",
+        "util.promisify": "1.0.0"
+      },
+      "dependencies": {
+        "util.promisify": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz",
+          "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==",
+          "dev": true,
+          "requires": {
+            "define-properties": "^1.1.2",
+            "object.getownpropertydescriptors": "^2.0.3"
+          }
+        }
+      }
+    },
+    "htmlparser2": {
+      "version": "3.10.1",
+      "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
+      "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
+      "dev": true,
+      "requires": {
+        "domelementtype": "^1.3.1",
+        "domhandler": "^2.3.0",
+        "domutils": "^1.5.1",
+        "entities": "^1.1.1",
+        "inherits": "^2.0.1",
+        "readable-stream": "^3.1.1"
+      },
+      "dependencies": {
+        "entities": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
+          "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        }
+      }
+    },
+    "http-deceiver": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
+      "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=",
+      "dev": true
+    },
+    "http-errors": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+      "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+      "dev": true,
+      "requires": {
+        "depd": "~1.1.2",
+        "inherits": "2.0.3",
+        "setprototypeof": "1.1.1",
+        "statuses": ">= 1.5.0 < 2",
+        "toidentifier": "1.0.0"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+          "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+          "dev": true
+        }
+      }
+    },
+    "http-parser-js": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.2.tgz",
+      "integrity": "sha512-opCO9ASqg5Wy2FNo7A0sxy71yGbbkJJXLdgMK04Tcypw9jr2MgWbyubb0+WdmDmGnFflO7fRbqbaihh/ENDlRQ==",
+      "dev": true
+    },
+    "http-proxy": {
+      "version": "1.18.1",
+      "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
+      "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
+      "dev": true,
+      "requires": {
+        "eventemitter3": "^4.0.0",
+        "follow-redirects": "^1.0.0",
+        "requires-port": "^1.0.0"
+      }
+    },
+    "http-proxy-middleware": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-1.0.4.tgz",
+      "integrity": "sha512-8wiqujNWlsZNbeTSSWMLUl/u70xbJ5VYRwPR8RcAbvsNxzAZbgwLzRvT96btbm3fAitZUmo5i8LY6WKGyHDgvA==",
+      "dev": true,
+      "requires": {
+        "@types/http-proxy": "^1.17.4",
+        "http-proxy": "^1.18.1",
+        "is-glob": "^4.0.1",
+        "lodash": "^4.17.15",
+        "micromatch": "^4.0.2"
+      },
+      "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,
+          "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,
+          "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
+        },
+        "micromatch": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+          "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+          "dev": true,
+          "requires": {
+            "braces": "^3.0.1",
+            "picomatch": "^2.0.5"
+          }
+        },
+        "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"
+          }
+        }
+      }
+    },
+    "http-signature": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0",
+        "jsprim": "^1.2.2",
+        "sshpk": "^1.7.0"
+      }
+    },
+    "https-browserify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
+      "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
+      "dev": true
+    },
+    "human-signals": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
+      "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
+      "dev": true
+    },
+    "husky": {
+      "version": "4.2.5",
+      "resolved": "https://registry.npmjs.org/husky/-/husky-4.2.5.tgz",
+      "integrity": "sha512-SYZ95AjKcX7goYVZtVZF2i6XiZcHknw50iXvY7b0MiGoj5RwdgRQNEHdb+gPDPCXKlzwrybjFjkL6FOj8uRhZQ==",
+      "dev": true,
+      "requires": {
+        "chalk": "^4.0.0",
+        "ci-info": "^2.0.0",
+        "compare-versions": "^3.6.0",
+        "cosmiconfig": "^6.0.0",
+        "find-versions": "^3.2.0",
+        "opencollective-postinstall": "^2.0.2",
+        "pkg-dir": "^4.2.0",
+        "please-upgrade-node": "^3.2.0",
+        "slash": "^3.0.0",
+        "which-pm-runs": "^1.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
+          "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "cosmiconfig": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
+          "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==",
+          "dev": true,
+          "requires": {
+            "@types/parse-json": "^4.0.0",
+            "import-fresh": "^3.1.0",
+            "parse-json": "^5.0.0",
+            "path-type": "^4.0.0",
+            "yaml": "^1.7.2"
+          }
+        },
+        "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
+        },
+        "path-type": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+          "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+          "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"
+          }
+        }
+      }
+    },
+    "hyphenate-style-name": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz",
+      "integrity": "sha512-EcuixamT82oplpoJ2XU4pDtKGWQ7b00CD9f1ug9IaQ3p1bkHMiKCZ9ut9QDI6qsa6cpUuB+A/I+zLtdNK4n2DQ=="
+    },
+    "iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "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"
+      }
+    },
+    "identity-obj-proxy": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz",
+      "integrity": "sha1-lNK9qWCERT7zb7xarsN+D3nx/BQ=",
+      "dev": true,
+      "requires": {
+        "harmony-reflect": "^1.4.6"
+      }
+    },
+    "ieee754": {
+      "version": "1.1.13",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
+      "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==",
+      "dev": true
+    },
+    "iferr": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
+      "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
+      "dev": true
+    },
+    "ignore": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+      "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+      "dev": true
+    },
+    "image-size": {
+      "version": "0.5.5",
+      "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
+      "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
+      "dev": true,
+      "optional": true
+    },
+    "immer": {
+      "version": "6.0.9",
+      "resolved": "https://registry.npmjs.org/immer/-/immer-6.0.9.tgz",
+      "integrity": "sha512-SyCYnAuiRf67Lvk0VkwFvwtDoEiCMjeamnHvRfnVDyc7re1/rQrNxuL+jJ7lA3WvdC4uznrvbmm+clJ9+XXatg=="
+    },
+    "import-cwd": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz",
+      "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=",
+      "dev": true,
+      "requires": {
+        "import-from": "^2.1.0"
+      }
+    },
+    "import-fresh": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
+      "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==",
+      "dev": true,
+      "requires": {
+        "parent-module": "^1.0.0",
+        "resolve-from": "^4.0.0"
+      },
+      "dependencies": {
+        "resolve-from": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+          "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+          "dev": true
+        }
+      }
+    },
+    "import-from": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz",
+      "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=",
+      "dev": true,
+      "requires": {
+        "resolve-from": "^3.0.0"
+      },
+      "dependencies": {
+        "resolve-from": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+          "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+          "dev": true
+        }
+      }
+    },
+    "import-lazy": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz",
+      "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==",
+      "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"
+      },
+      "dependencies": {
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^3.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "p-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
+        },
+        "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"
+          }
+        }
+      }
+    },
+    "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.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+    },
+    "ini": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+      "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
+      "dev": true
+    },
+    "inquirer": {
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.0.tgz",
+      "integrity": "sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA==",
+      "dev": true,
+      "requires": {
+        "ansi-escapes": "^3.2.0",
+        "chalk": "^2.4.2",
+        "cli-cursor": "^2.1.0",
+        "cli-width": "^2.0.0",
+        "external-editor": "^3.0.3",
+        "figures": "^2.0.0",
+        "lodash": "^4.17.12",
+        "mute-stream": "0.0.7",
+        "run-async": "^2.2.0",
+        "rxjs": "^6.4.0",
+        "string-width": "^2.1.0",
+        "strip-ansi": "^5.1.0",
+        "through": "^2.3.6"
+      }
+    },
+    "insert-css": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/insert-css/-/insert-css-2.0.0.tgz",
+      "integrity": "sha1-610Ql7dUL0x56jBg067gfQU4gPQ="
+    },
+    "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"
+      }
+    },
+    "internal-slot": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz",
+      "integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==",
+      "dev": true,
+      "requires": {
+        "es-abstract": "^1.17.0-next.1",
+        "has": "^1.0.3",
+        "side-channel": "^1.0.2"
+      }
+    },
+    "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"
+      }
+    },
+    "invert-kv": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
+      "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
+      "dev": true
+    },
+    "ip": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
+      "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=",
+      "dev": true
+    },
+    "ip-regex": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
+      "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
+      "dev": true
+    },
+    "ipaddr.js": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+      "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+      "dev": true
+    },
+    "is-absolute-url": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz",
+      "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=",
+      "dev": true
+    },
+    "is-accessor-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "is-alphabetical": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
+      "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==",
+      "dev": true
+    },
+    "is-alphanumeric": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz",
+      "integrity": "sha1-Spzvcdr0wAHB2B1j0UDPU/1oifQ=",
+      "dev": true
+    },
+    "is-alphanumerical": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
+      "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
+      "dev": true,
+      "requires": {
+        "is-alphabetical": "^1.0.0",
+        "is-decimal": "^1.0.0"
+      }
+    },
+    "is-arguments": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz",
+      "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==",
+      "dev": true
+    },
+    "is-arrayish": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+      "dev": true
+    },
+    "is-binary-path": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+      "dev": true,
+      "requires": {
+        "binary-extensions": "^2.0.0"
+      }
+    },
+    "is-buffer": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+      "dev": true
+    },
+    "is-callable": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz",
+      "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==",
+      "dev": true
+    },
+    "is-ci": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+      "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+      "dev": true,
+      "requires": {
+        "ci-info": "^2.0.0"
+      }
+    },
+    "is-color-stop": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz",
+      "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=",
+      "dev": true,
+      "requires": {
+        "css-color-names": "^0.0.4",
+        "hex-color-regex": "^1.1.0",
+        "hsl-regex": "^1.0.0",
+        "hsla-regex": "^1.0.0",
+        "rgb-regex": "^1.0.1",
+        "rgba-regex": "^1.0.0"
+      }
+    },
+    "is-data-descriptor": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "is-date-object": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
+      "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
+      "dev": true
+    },
+    "is-decimal": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
+      "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==",
+      "dev": true
+    },
+    "is-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+      "dev": true,
+      "requires": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "is-directory": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
+      "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
+      "dev": true
+    },
+    "is-docker": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz",
+      "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==",
+      "dev": true
+    },
+    "is-extendable": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+      "dev": true
+    },
+    "is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+      "dev": true
+    },
+    "is-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-generator-fn": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
+      "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
+      "dev": true
+    },
+    "is-glob": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+      "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+      "dev": true,
+      "requires": {
+        "is-extglob": "^2.1.1"
+      }
+    },
+    "is-hexadecimal": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz",
+      "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==",
+      "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": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "is-obj": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+      "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
+      "dev": true
+    },
+    "is-path-cwd": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
+      "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
+      "dev": true
+    },
+    "is-path-in-cwd": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz",
+      "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==",
+      "dev": true,
+      "requires": {
+        "is-path-inside": "^2.1.0"
+      }
+    },
+    "is-path-inside": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz",
+      "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==",
+      "dev": true,
+      "requires": {
+        "path-is-inside": "^1.0.2"
+      }
+    },
+    "is-plain-obj": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+      "dev": true
+    },
+    "is-plain-object": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.1"
+      }
+    },
+    "is-regex": {
+      "version": "1.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-regexp": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
+      "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=",
+      "dev": true
+    },
+    "is-resolvable": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
+      "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
+      "dev": true
+    },
+    "is-root": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz",
+      "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==",
+      "dev": true
+    },
+    "is-stream": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
+    },
+    "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-svg": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz",
... 11853 lines suppressed ...