From cc0cc154b9506d1961d08cb29fbc29ad815bad69 Mon Sep 17 00:00:00 2001
From: crupest <crupest@outlook.com>
Date: Mon, 24 Aug 2020 22:59:45 +0800
Subject: ...

---
 Timeline/ClientApp/src/app/user/UserInfoCard.tsx | 210 +++++++++++------------
 1 file changed, 105 insertions(+), 105 deletions(-)

(limited to 'Timeline/ClientApp/src/app/user/UserInfoCard.tsx')

diff --git a/Timeline/ClientApp/src/app/user/UserInfoCard.tsx b/Timeline/ClientApp/src/app/user/UserInfoCard.tsx
index 0f321f32..9ce46e3c 100644
--- a/Timeline/ClientApp/src/app/user/UserInfoCard.tsx
+++ b/Timeline/ClientApp/src/app/user/UserInfoCard.tsx
@@ -1,105 +1,105 @@
-import React from 'react';
-import clsx from 'clsx';
-import {
-  Dropdown,
-  DropdownToggle,
-  DropdownMenu,
-  DropdownItem,
-  Button,
-} from 'reactstrap';
-import { useTranslation } from 'react-i18next';
-import { fromEvent } from 'rxjs';
-
-import { timelineVisibilityTooltipTranslationMap } from '../data/timeline';
-import { useAvatar } from '../data/user';
-
-import { TimelineCardComponentProps } from '../timeline/TimelinePageTemplateUI';
-import BlobImage from '../common/BlobImage';
-
-export type PersonalTimelineManageItem = 'avatar' | 'nickname';
-
-export type UserInfoCardProps = TimelineCardComponentProps<
-  PersonalTimelineManageItem
->;
-
-const UserInfoCard: React.FC<UserInfoCardProps> = (props) => {
-  const { onHeight, onManage } = props;
-  const { t } = useTranslation();
-
-  const avatar = useAvatar(props.timeline.owner.username);
-
-  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-  const containerRef = React.useRef<HTMLDivElement>(null!);
-
-  const notifyHeight = React.useCallback((): void => {
-    if (onHeight) {
-      onHeight(containerRef.current.getBoundingClientRect().height);
-    }
-  }, [onHeight]);
-
-  React.useEffect(() => {
-    const subscription = fromEvent(window, 'resize').subscribe(notifyHeight);
-    return () => subscription.unsubscribe();
-  });
-
-  const [manageDropdownOpen, setManageDropdownOpen] = React.useState<boolean>(
-    false
-  );
-  const toggleManageDropdown = React.useCallback(
-    (): void => setManageDropdownOpen((old) => !old),
-    []
-  );
-
-  return (
-    <div
-      ref={containerRef}
-      className={clsx('rounded border bg-light p-2', props.className)}
-      onTransitionEnd={notifyHeight}
-    >
-      <BlobImage
-        blob={avatar}
-        onLoad={notifyHeight}
-        className="avatar large mr-2 mb-2 rounded-circle float-left"
-      />
-      <div>
-        {props.timeline.owner.nickname}
-        <small className="ml-3 text-secondary">
-          @{props.timeline.owner.username}
-        </small>
-      </div>
-      <p className="mb-0">{props.timeline.description}</p>
-      <small className="mt-1 d-block">
-        {t(timelineVisibilityTooltipTranslationMap[props.timeline.visibility])}
-      </small>
-      <div className="text-right mt-2">
-        {onManage != null ? (
-          <Dropdown isOpen={manageDropdownOpen} toggle={toggleManageDropdown}>
-            <DropdownToggle outline color="primary">
-              {t('timeline.manage')}
-            </DropdownToggle>
-            <DropdownMenu>
-              <DropdownItem onClick={() => onManage('nickname')}>
-                {t('timeline.manageItem.nickname')}
-              </DropdownItem>
-              <DropdownItem onClick={() => onManage('avatar')}>
-                {t('timeline.manageItem.avatar')}
-              </DropdownItem>
-              <DropdownItem onClick={() => onManage('property')}>
-                {t('timeline.manageItem.property')}
-              </DropdownItem>
-              <DropdownItem onClick={props.onMember}>
-                {t('timeline.manageItem.member')}
-              </DropdownItem>
-            </DropdownMenu>
-          </Dropdown>
-        ) : (
-          <Button color="primary" outline onClick={props.onMember}>
-            {t('timeline.memberButton')}
-          </Button>
-        )}
-      </div>
-    </div>
-  );
-};
-
-export default UserInfoCard;
+import React from "react";
+import clsx from "clsx";
+import {
+  Dropdown,
+  DropdownToggle,
+  DropdownMenu,
+  DropdownItem,
+  Button,
+} from "reactstrap";
+import { useTranslation } from "react-i18next";
+import { fromEvent } from "rxjs";
+
+import { timelineVisibilityTooltipTranslationMap } from "../data/timeline";
+import { useAvatar } from "../data/user";
+
+import { TimelineCardComponentProps } from "../timeline/TimelinePageTemplateUI";
+import BlobImage from "../common/BlobImage";
+
+export type PersonalTimelineManageItem = "avatar" | "nickname";
+
+export type UserInfoCardProps = TimelineCardComponentProps<
+  PersonalTimelineManageItem
+>;
+
+const UserInfoCard: React.FC<UserInfoCardProps> = (props) => {
+  const { onHeight, onManage } = props;
+  const { t } = useTranslation();
+
+  const avatar = useAvatar(props.timeline.owner.username);
+
+  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+  const containerRef = React.useRef<HTMLDivElement>(null!);
+
+  const notifyHeight = React.useCallback((): void => {
+    if (onHeight) {
+      onHeight(containerRef.current.getBoundingClientRect().height);
+    }
+  }, [onHeight]);
+
+  React.useEffect(() => {
+    const subscription = fromEvent(window, "resize").subscribe(notifyHeight);
+    return () => subscription.unsubscribe();
+  });
+
+  const [manageDropdownOpen, setManageDropdownOpen] = React.useState<boolean>(
+    false
+  );
+  const toggleManageDropdown = React.useCallback(
+    (): void => setManageDropdownOpen((old) => !old),
+    []
+  );
+
+  return (
+    <div
+      ref={containerRef}
+      className={clsx("rounded border bg-light p-2", props.className)}
+      onTransitionEnd={notifyHeight}
+    >
+      <BlobImage
+        blob={avatar}
+        onLoad={notifyHeight}
+        className="avatar large mr-2 mb-2 rounded-circle float-left"
+      />
+      <div>
+        {props.timeline.owner.nickname}
+        <small className="ml-3 text-secondary">
+          @{props.timeline.owner.username}
+        </small>
+      </div>
+      <p className="mb-0">{props.timeline.description}</p>
+      <small className="mt-1 d-block">
+        {t(timelineVisibilityTooltipTranslationMap[props.timeline.visibility])}
+      </small>
+      <div className="text-right mt-2">
+        {onManage != null ? (
+          <Dropdown isOpen={manageDropdownOpen} toggle={toggleManageDropdown}>
+            <DropdownToggle outline color="primary">
+              {t("timeline.manage")}
+            </DropdownToggle>
+            <DropdownMenu>
+              <DropdownItem onClick={() => onManage("nickname")}>
+                {t("timeline.manageItem.nickname")}
+              </DropdownItem>
+              <DropdownItem onClick={() => onManage("avatar")}>
+                {t("timeline.manageItem.avatar")}
+              </DropdownItem>
+              <DropdownItem onClick={() => onManage("property")}>
+                {t("timeline.manageItem.property")}
+              </DropdownItem>
+              <DropdownItem onClick={props.onMember}>
+                {t("timeline.manageItem.member")}
+              </DropdownItem>
+            </DropdownMenu>
+          </Dropdown>
+        ) : (
+          <Button color="primary" outline onClick={props.onMember}>
+            {t("timeline.memberButton")}
+          </Button>
+        )}
+      </div>
+    </div>
+  );
+};
+
+export default UserInfoCard;
-- 
cgit v1.2.3


From 8e297d2b659f447814e07676423e973f0f41e560 Mon Sep 17 00:00:00 2001
From: crupest <crupest@outlook.com>
Date: Mon, 24 Aug 2020 23:51:20 +0800
Subject: ...

---
 Timeline/ClientApp/.eslintignore                   |   1 -
 Timeline/ClientApp/.eslintrc.js                    |  58 ++--
 Timeline/ClientApp/.pnp.js                         | 360 +++++++++++++++++++++
 Timeline/ClientApp/package.json                    |   2 +
 Timeline/ClientApp/src/app/App.tsx                 |   1 -
 Timeline/ClientApp/src/app/about/About.tsx         |   4 +-
 Timeline/ClientApp/src/app/admin/Admin.tsx         |   4 +-
 Timeline/ClientApp/src/app/admin/UserAdmin.tsx     |   1 -
 Timeline/ClientApp/src/app/common/AlertHost.tsx    |   4 +-
 Timeline/ClientApp/src/app/data/timeline.ts        |  18 +-
 Timeline/ClientApp/src/app/data/user.ts            |   7 +-
 Timeline/ClientApp/src/app/home/BoardWithUser.tsx  |   1 -
 .../ClientApp/src/app/home/BoardWithoutUser.tsx    |   1 -
 Timeline/ClientApp/src/app/home/Home.tsx           |   2 +-
 Timeline/ClientApp/src/app/home/OfflineBoard.tsx   |   1 -
 Timeline/ClientApp/src/app/home/TimelineBoard.tsx  |   1 -
 .../src/app/home/TimelineCreateDialog.tsx          |   1 -
 Timeline/ClientApp/src/app/http/mock/user.ts       |   1 -
 Timeline/ClientApp/src/app/http/timeline.ts        |   1 +
 Timeline/ClientApp/src/app/settings/Settings.tsx   |   1 -
 .../src/app/timeline/TimelineInfoCard.tsx          |   2 +-
 .../ClientApp/src/app/timeline/TimelineItem.tsx    |   2 -
 .../ClientApp/src/app/timeline/TimelineMember.tsx  |   1 -
 .../ClientApp/src/app/timeline/TimelinePage.tsx    |   3 +-
 .../src/app/timeline/TimelinePageTemplate.tsx      |   2 +-
 .../src/app/timeline/TimelinePageTemplateUI.tsx    |   3 +-
 .../src/app/timeline/TimelinePostEdit.tsx          |   2 -
 .../app/timeline/TimelinePropertyChangeDialog.tsx  |   1 -
 Timeline/ClientApp/src/app/user/Login.tsx          |   7 +-
 Timeline/ClientApp/src/app/user/User.tsx           |   4 +-
 Timeline/ClientApp/src/app/user/UserInfoCard.tsx   |   1 -
 Timeline/ClientApp/src/app/user/UserPage.tsx       |   2 +-
 Timeline/ClientApp/yarn.lock                       | 355 +++++++++++++++++++-
 33 files changed, 768 insertions(+), 87 deletions(-)

(limited to 'Timeline/ClientApp/src/app/user/UserInfoCard.tsx')

diff --git a/Timeline/ClientApp/.eslintignore b/Timeline/ClientApp/.eslintignore
index 371b5fcb..de5aa4fc 100644
--- a/Timeline/ClientApp/.eslintignore
+++ b/Timeline/ClientApp/.eslintignore
@@ -1,5 +1,4 @@
 .yarn
 node_modules
 dist
-webpack.*.js
 .eslintrc.js
diff --git a/Timeline/ClientApp/.eslintrc.js b/Timeline/ClientApp/.eslintrc.js
index 2013f23d..830a2aa4 100644
--- a/Timeline/ClientApp/.eslintrc.js
+++ b/Timeline/ClientApp/.eslintrc.js
@@ -1,48 +1,62 @@
+const path = require("path");
+
 module.exports = {
   env: {
     browser: true,
-    es6: true,
+    es2020: true,
   },
   extends: [
-    'eslint:recommended',
-    'plugin:react/recommended',
-    'plugin:@typescript-eslint/eslint-recommended',
-    'plugin:@typescript-eslint/recommended',
-    'plugin:@typescript-eslint/recommended-requiring-type-checking',
-    'plugin:prettier/recommended',
-    'prettier/react',
-    'prettier/@typescript-eslint',
-    'plugin:react-hooks/recommended',
+    "eslint:recommended",
+    "plugin:react/recommended",
+    "plugin:@typescript-eslint/eslint-recommended",
+    "plugin:@typescript-eslint/recommended",
+    "plugin:@typescript-eslint/recommended-requiring-type-checking",
+    "plugin:prettier/recommended",
+    "prettier/react",
+    "prettier/@typescript-eslint",
+    "plugin:react-hooks/recommended",
+    "plugin:import/recommended",
+    "plugin:import/typescript",
   ],
   globals: {
-    Atomics: 'readonly',
-    SharedArrayBuffer: 'readonly',
+    Atomics: "readonly",
+    SharedArrayBuffer: "readonly",
   },
-  parser: '@typescript-eslint/parser',
+  parser: "@typescript-eslint/parser",
   parserOptions: {
-    project: ['./src/app/tsconfig.json', './src/sw/tsconfig.json'],
+    project: ["./src/app/tsconfig.json", "./src/sw/tsconfig.json"],
     ecmaFeatures: {
       jsx: true,
     },
-    ecmaVersion: 2018,
-    sourceType: 'module',
+    sourceType: "module",
   },
-  plugins: ['react', '@typescript-eslint', 'react-hooks'],
+  plugins: ["react", "@typescript-eslint", "react-hooks", "import"],
   settings: {
     react: {
-      version: 'detect',
+      version: "detect",
+    },
+    "import/resolver": {
+      webpack: {
+        config: path.resolve(__dirname, "webpack.config.dev.js"),
+      },
     },
   },
   rules: {
-    'react/prop-types': 'off',
-    '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
-    '@typescript-eslint/explicit-function-return-type': [
-      'warn',
+    "react/prop-types": "off",
+    "@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }],
+    "@typescript-eslint/explicit-function-return-type": [
+      "warn",
       {
         allowExpressions: true,
         allowTypedFunctionExpressions: true,
         allowHigherOrderFunctions: true,
       },
     ],
+    "import/order": [
+      "warn",
+      {
+        "newlines-between": "always",
+      },
+    ],
   },
 };
diff --git a/Timeline/ClientApp/.pnp.js b/Timeline/ClientApp/.pnp.js
index 4b0d0ff5..ef53bd2c 100644
--- a/Timeline/ClientApp/.pnp.js
+++ b/Timeline/ClientApp/.pnp.js
@@ -185,6 +185,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
         "eslint-config-prettier",
         "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:6.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-config-prettier%2Fdownload%2Feslint-config-prettier-6.11.0.tgz"
       ],
+      [
+        "eslint-import-resolver-webpack",
+        "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:0.12.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-import-resolver-webpack%2Fdownload%2Feslint-import-resolver-webpack-0.12.2.tgz"
+      ],
+      [
+        "eslint-plugin-import",
+        "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:2.22.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-import%2Fdownload%2Feslint-plugin-import-2.22.0.tgz"
+      ],
       [
         "eslint-plugin-prettier",
         "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.1.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-prettier%2Fdownload%2Feslint-plugin-prettier-3.1.4.tgz"
@@ -404,6 +412,8 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
             ["css-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.2.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-loader%2Fdownload%2Fcss-loader-4.2.1.tgz"],
             ["eslint", "npm:7.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.7.0.tgz"],
             ["eslint-config-prettier", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:6.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-config-prettier%2Fdownload%2Feslint-config-prettier-6.11.0.tgz"],
+            ["eslint-import-resolver-webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:0.12.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-import-resolver-webpack%2Fdownload%2Feslint-import-resolver-webpack-0.12.2.tgz"],
+            ["eslint-plugin-import", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:2.22.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-import%2Fdownload%2Feslint-plugin-import-2.22.0.tgz"],
             ["eslint-plugin-prettier", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.1.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-prettier%2Fdownload%2Feslint-plugin-prettier-3.1.4.tgz"],
             ["eslint-plugin-react", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.20.6::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-react%2Fdownload%2Feslint-plugin-react-7.20.6.tgz"],
             ["eslint-plugin-react-hooks", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-react-hooks%2Fdownload%2Feslint-plugin-react-hooks-4.1.0.tgz"],
@@ -3291,6 +3301,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
           "linkType": "HARD",
         }]
       ]],
+      ["@types/json5", [
+        ["npm:0.0.29::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fjson5%2Fdownload%2F%40types%2Fjson5-0.0.29.tgz", {
+          "packageLocation": "./.yarn/cache/@types-json5-npm-0.0.29-663cfa6df5-66e9ac0143.zip/node_modules/@types/json5/",
+          "packageDependencies": [
+            ["@types/json5", "npm:0.0.29::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fjson5%2Fdownload%2F%40types%2Fjson5-0.0.29.tgz"]
+          ],
+          "linkType": "HARD",
+        }]
+      ]],
       ["@types/keyv", [
         ["npm:3.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fkeyv%2Fdownload%2F%40types%2Fkeyv-3.1.1.tgz", {
           "packageLocation": "./.yarn/cache/@types-keyv-npm-3.1.1-f9769fb0ae-3aaf557d5b.zip/node_modules/@types/keyv/",
@@ -4251,6 +4270,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
           "linkType": "HARD",
         }]
       ]],
+      ["array-find", [
+        ["npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-find%2Fdownload%2Farray-find-1.0.0.tgz", {
+          "packageLocation": "./.yarn/cache/array-find-npm-1.0.0-93a6fccf45-1f6f5270a3.zip/node_modules/array-find/",
+          "packageDependencies": [
+            ["array-find", "npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-find%2Fdownload%2Farray-find-1.0.0.tgz"]
+          ],
+          "linkType": "HARD",
+        }]
+      ]],
       ["array-flatten", [
         ["npm:1.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-flatten%2Fdownload%2Farray-flatten-1.1.1.tgz", {
           "packageLocation": "./.yarn/cache/array-flatten-npm-1.1.1-612a788b2c-de7a056451.zip/node_modules/array-flatten/",
@@ -4314,6 +4342,17 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
           "linkType": "HARD",
         }]
       ]],
+      ["array.prototype.flat", [
+        ["npm:1.2.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray.prototype.flat%2Fdownload%2Farray.prototype.flat-1.2.3.tgz", {
+          "packageLocation": "./.yarn/cache/array.prototype.flat-npm-1.2.3-d28d243808-f88a474d1c.zip/node_modules/array.prototype.flat/",
+          "packageDependencies": [
+            ["array.prototype.flat", "npm:1.2.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray.prototype.flat%2Fdownload%2Farray.prototype.flat-1.2.3.tgz"],
+            ["define-properties", "npm:1.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdefine-properties%2Fdownload%2Fdefine-properties-1.1.3.tgz"],
+            ["es-abstract", "npm:1.17.6::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fes-abstract%2Fdownload%2Fes-abstract-1.17.6.tgz"]
+          ],
+          "linkType": "HARD",
+        }]
+      ]],
       ["array.prototype.flatmap", [
         ["npm:1.2.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray.prototype.flatmap%2Fdownload%2Farray.prototype.flatmap-1.2.3.tgz", {
           "packageLocation": "./.yarn/cache/array.prototype.flatmap-npm-1.2.3-fddf0cc1de-adbf30f271.zip/node_modules/array.prototype.flatmap/",
@@ -5676,6 +5715,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
           "linkType": "HARD",
         }]
       ]],
+      ["contains-path", [
+        ["npm:0.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcontains-path%2Fdownload%2Fcontains-path-0.1.0.tgz", {
+          "packageLocation": "./.yarn/cache/contains-path-npm-0.1.0-bf2953afcb-59920a59a0.zip/node_modules/contains-path/",
+          "packageDependencies": [
+            ["contains-path", "npm:0.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcontains-path%2Fdownload%2Fcontains-path-0.1.0.tgz"]
+          ],
+          "linkType": "HARD",
+        }]
+      ]],
       ["content-disposition", [
         ["npm:0.5.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcontent-disposition%2Fdownload%2Fcontent-disposition-0.5.3.tgz", {
           "packageLocation": "./.yarn/cache/content-disposition-npm-0.5.3-e98afeed39-8f1f235c04.zip/node_modules/content-disposition/",
@@ -6428,6 +6476,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
         }]
       ]],
       ["doctrine", [
+        ["npm:1.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdoctrine%2Fdownload%2Fdoctrine-1.5.0.tgz", {
+          "packageLocation": "./.yarn/cache/doctrine-npm-1.5.0-53163999e1-aaffea02f9.zip/node_modules/doctrine/",
+          "packageDependencies": [
+            ["doctrine", "npm:1.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdoctrine%2Fdownload%2Fdoctrine-1.5.0.tgz"],
+            ["esutils", "npm:2.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fesutils%2Fdownload%2Fesutils-2.0.3.tgz"],
+            ["isarray", "npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fisarray%2Fdownload%2Fisarray-1.0.0.tgz"]
+          ],
+          "linkType": "HARD",
+        }],
         ["npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdoctrine%2Fdownload%2Fdoctrine-2.1.0.tgz", {
           "packageLocation": "./.yarn/cache/doctrine-npm-2.1.0-4199f60fea-4aa55e4675.zip/node_modules/doctrine/",
           "packageDependencies": [
@@ -6684,6 +6741,16 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
         }]
       ]],
       ["enhanced-resolve", [
+        ["npm:0.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fenhanced-resolve%2Fdownload%2Fenhanced-resolve-0.9.1.tgz", {
+          "packageLocation": "./.yarn/cache/enhanced-resolve-npm-0.9.1-447a118155-c814cd9282.zip/node_modules/enhanced-resolve/",
+          "packageDependencies": [
+            ["enhanced-resolve", "npm:0.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fenhanced-resolve%2Fdownload%2Fenhanced-resolve-0.9.1.tgz"],
+            ["graceful-fs", "npm:4.2.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fgraceful-fs%2Fdownload%2Fgraceful-fs-4.2.4.tgz"],
+            ["memory-fs", "npm:0.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fmemory-fs%2Fdownload%2Fmemory-fs-0.2.0.tgz"],
+            ["tapable", "npm:0.1.10::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftapable%2Fdownload%2Ftapable-0.1.10.tgz"]
+          ],
+          "linkType": "HARD",
+        }],
         ["npm:4.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fenhanced-resolve%2Fdownload%2Fenhanced-resolve-4.3.0.tgz", {
           "packageLocation": "./.yarn/cache/enhanced-resolve-npm-4.3.0-a66c6355f8-aecdc0b208.zip/node_modules/enhanced-resolve/",
           "packageDependencies": [
@@ -6868,6 +6935,79 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
           "linkType": "HARD",
         }]
       ]],
+      ["eslint-import-resolver-node", [
+        ["npm:0.3.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-import-resolver-node%2Fdownload%2Feslint-import-resolver-node-0.3.4.tgz", {
+          "packageLocation": "./.yarn/cache/eslint-import-resolver-node-npm-0.3.4-7b7632365b-825e34e662.zip/node_modules/eslint-import-resolver-node/",
+          "packageDependencies": [
+            ["eslint-import-resolver-node", "npm:0.3.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-import-resolver-node%2Fdownload%2Feslint-import-resolver-node-0.3.4.tgz"],
+            ["debug", "virtual:8c8a8763bc4d11063ade310ae62bd0668563a9ee3e13ffce549c878905c5cfe13a5d3cbcb6ca33a1c75125112870784d9f483ab0575378e363fa1033ba794f97#npm:2.6.9::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz"],
+            ["resolve", "patch:resolve@npm%3A1.17.0%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Fresolve%252Fdownload%252Fresolve-1.17.0.tgz#builtin<compat/resolve>::version=1.17.0&hash=3388aa"]
+          ],
+          "linkType": "HARD",
+        }]
+      ]],
+      ["eslint-import-resolver-webpack", [
+        ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:0.12.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-import-resolver-webpack%2Fdownload%2Feslint-import-resolver-webpack-0.12.2.tgz", {
+          "packageLocation": "./.yarn/$$virtual/eslint-import-resolver-webpack-virtual-3187d8a474/0/cache/eslint-import-resolver-webpack-npm-0.12.2-e8bad217fb-5310d4383e.zip/node_modules/eslint-import-resolver-webpack/",
+          "packageDependencies": [
+            ["eslint-import-resolver-webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:0.12.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-import-resolver-webpack%2Fdownload%2Feslint-import-resolver-webpack-0.12.2.tgz"],
+            ["array-find", "npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-find%2Fdownload%2Farray-find-1.0.0.tgz"],
+            ["debug", "virtual:8c8a8763bc4d11063ade310ae62bd0668563a9ee3e13ffce549c878905c5cfe13a5d3cbcb6ca33a1c75125112870784d9f483ab0575378e363fa1033ba794f97#npm:2.6.9::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz"],
+            ["enhanced-resolve", "npm:0.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fenhanced-resolve%2Fdownload%2Fenhanced-resolve-0.9.1.tgz"],
+            ["eslint-plugin-import", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:2.22.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-import%2Fdownload%2Feslint-plugin-import-2.22.0.tgz"],
+            ["find-root", "npm:1.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-root%2Fdownload%2Ffind-root-1.1.0.tgz"],
+            ["has", "npm:1.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas%2Fdownload%2Fhas-1.0.3.tgz"],
+            ["interpret", "npm:1.4.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Finterpret%2Fdownload%2Finterpret-1.4.0.tgz"],
+            ["lodash", "npm:4.17.19::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.19.tgz"],
+            ["node-libs-browser", "npm:2.2.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-libs-browser%2Fdownload%2Fnode-libs-browser-2.2.1.tgz"],
+            ["resolve", "patch:resolve@npm%3A1.17.0%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Fresolve%252Fdownload%252Fresolve-1.17.0.tgz#builtin<compat/resolve>::version=1.17.0&hash=3388aa"],
+            ["semver", "npm:5.7.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz"],
+            ["webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"]
+          ],
+          "packagePeers": [
+            "eslint-plugin-import",
+            "webpack"
+          ],
+          "linkType": "HARD",
+        }]
+      ]],
+      ["eslint-module-utils", [
+        ["npm:2.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-module-utils%2Fdownload%2Feslint-module-utils-2.6.0.tgz", {
+          "packageLocation": "./.yarn/cache/eslint-module-utils-npm-2.6.0-57b7c7dc6a-f584af1764.zip/node_modules/eslint-module-utils/",
+          "packageDependencies": [
+            ["eslint-module-utils", "npm:2.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-module-utils%2Fdownload%2Feslint-module-utils-2.6.0.tgz"],
+            ["debug", "virtual:8c8a8763bc4d11063ade310ae62bd0668563a9ee3e13ffce549c878905c5cfe13a5d3cbcb6ca33a1c75125112870784d9f483ab0575378e363fa1033ba794f97#npm:2.6.9::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz"],
+            ["pkg-dir", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpkg-dir%2Fdownload%2Fpkg-dir-2.0.0.tgz"]
+          ],
+          "linkType": "HARD",
+        }]
+      ]],
+      ["eslint-plugin-import", [
+        ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:2.22.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-import%2Fdownload%2Feslint-plugin-import-2.22.0.tgz", {
+          "packageLocation": "./.yarn/$$virtual/eslint-plugin-import-virtual-bb7e8375cb/0/cache/eslint-plugin-import-npm-2.22.0-e8b10e811e-ad41aec63d.zip/node_modules/eslint-plugin-import/",
+          "packageDependencies": [
+            ["eslint-plugin-import", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:2.22.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-import%2Fdownload%2Feslint-plugin-import-2.22.0.tgz"],
+            ["array-includes", "npm:3.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-includes%2Fdownload%2Farray-includes-3.1.1.tgz"],
+            ["array.prototype.flat", "npm:1.2.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray.prototype.flat%2Fdownload%2Farray.prototype.flat-1.2.3.tgz"],
+            ["contains-path", "npm:0.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcontains-path%2Fdownload%2Fcontains-path-0.1.0.tgz"],
+            ["debug", "virtual:8c8a8763bc4d11063ade310ae62bd0668563a9ee3e13ffce549c878905c5cfe13a5d3cbcb6ca33a1c75125112870784d9f483ab0575378e363fa1033ba794f97#npm:2.6.9::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz"],
+            ["doctrine", "npm:1.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdoctrine%2Fdownload%2Fdoctrine-1.5.0.tgz"],
+            ["eslint", "npm:7.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.7.0.tgz"],
+            ["eslint-import-resolver-node", "npm:0.3.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-import-resolver-node%2Fdownload%2Feslint-import-resolver-node-0.3.4.tgz"],
+            ["eslint-module-utils", "npm:2.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-module-utils%2Fdownload%2Feslint-module-utils-2.6.0.tgz"],
+            ["has", "npm:1.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas%2Fdownload%2Fhas-1.0.3.tgz"],
+            ["minimatch", "npm:3.0.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fminimatch%2Fdownload%2Fminimatch-3.0.4.tgz"],
+            ["object.values", "npm:1.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fobject.values%2Fdownload%2Fobject.values-1.1.1.tgz"],
+            ["read-pkg-up", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fread-pkg-up%2Fdownload%2Fread-pkg-up-2.0.0.tgz"],
+            ["resolve", "patch:resolve@npm%3A1.17.0%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Fresolve%252Fdownload%252Fresolve-1.17.0.tgz#builtin<compat/resolve>::version=1.17.0&hash=3388aa"],
+            ["tsconfig-paths", "npm:3.9.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsconfig-paths%2Fdownload%2Ftsconfig-paths-3.9.0.tgz"]
+          ],
+          "packagePeers": [
+            "eslint"
+          ],
+          "linkType": "HARD",
+        }]
+      ]],
       ["eslint-plugin-prettier", [
         ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.1.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-prettier%2Fdownload%2Feslint-plugin-prettier-3.1.4.tgz", {
           "packageLocation": "./.yarn/$$virtual/eslint-plugin-prettier-virtual-b3c2338d79/0/cache/eslint-plugin-prettier-npm-3.1.4-d88d887708-4e4df15579.zip/node_modules/eslint-plugin-prettier/",
@@ -7416,7 +7556,24 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
           "linkType": "HARD",
         }]
       ]],
+      ["find-root", [
+        ["npm:1.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-root%2Fdownload%2Ffind-root-1.1.0.tgz", {
+          "packageLocation": "./.yarn/cache/find-root-npm-1.1.0-80f44a9a17-34f9eeb725.zip/node_modules/find-root/",
+          "packageDependencies": [
+            ["find-root", "npm:1.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-root%2Fdownload%2Ffind-root-1.1.0.tgz"]
+          ],
+          "linkType": "HARD",
+        }]
+      ]],
       ["find-up", [
+        ["npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-2.1.0.tgz", {
+          "packageLocation": "./.yarn/cache/find-up-npm-2.1.0-cd7301714d-9dedb89f93.zip/node_modules/find-up/",
+          "packageDependencies": [
+            ["find-up", "npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-2.1.0.tgz"],
+            ["locate-path", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocate-path%2Fdownload%2Flocate-path-2.0.0.tgz"]
+          ],
+          "linkType": "HARD",
+        }],
         ["npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-3.0.0.tgz", {
           "packageLocation": "./.yarn/cache/find-up-npm-3.0.0-cee70ed7ef-c5422fc723.zip/node_modules/find-up/",
           "packageDependencies": [
@@ -8167,6 +8324,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
           "linkType": "HARD",
         }]
       ]],
+      ["hosted-git-info", [
+        ["npm:2.8.8::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhosted-git-info%2Fdownload%2Fhosted-git-info-2.8.8.tgz", {
+          "packageLocation": "./.yarn/cache/hosted-git-info-npm-2.8.8-7d1b32a089-3ecc389dc6.zip/node_modules/hosted-git-info/",
+          "packageDependencies": [
+            ["hosted-git-info", "npm:2.8.8::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhosted-git-info%2Fdownload%2Fhosted-git-info-2.8.8.tgz"]
+          ],
+          "linkType": "HARD",
+        }]
+      ]],
       ["hpack.js", [
         ["npm:2.1.6::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhpack.js%2Fdownload%2Fhpack.js-2.1.6.tgz", {
           "packageLocation": "./.yarn/cache/hpack.js-npm-2.1.6-23e0bbd2b9-a22a28aa31.zip/node_modules/hpack.js/",
@@ -9392,6 +9558,19 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
           "linkType": "HARD",
         }]
       ]],
+      ["load-json-file", [
+        ["npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fload-json-file%2Fdownload%2Fload-json-file-2.0.0.tgz", {
+          "packageLocation": "./.yarn/cache/load-json-file-npm-2.0.0-6c4dbfa60e-c6ea93d360.zip/node_modules/load-json-file/",
+          "packageDependencies": [
+            ["load-json-file", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fload-json-file%2Fdownload%2Fload-json-file-2.0.0.tgz"],
+            ["graceful-fs", "npm:4.2.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fgraceful-fs%2Fdownload%2Fgraceful-fs-4.2.4.tgz"],
+            ["parse-json", "npm:2.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse-json%2Fdownload%2Fparse-json-2.2.0.tgz"],
+            ["pify", "npm:2.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpify%2Fdownload%2Fpify-2.3.0.tgz"],
+            ["strip-bom", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-bom%2Fdownload%2Fstrip-bom-3.0.0.tgz"]
+          ],
+          "linkType": "HARD",
+        }]
+      ]],
       ["loader-runner", [
         ["npm:2.4.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-runner%2Fdownload%2Floader-runner-2.4.0.tgz", {
           "packageLocation": "./.yarn/cache/loader-runner-npm-2.4.0-ec901bb9ff-9173b602e8.zip/node_modules/loader-runner/",
@@ -9434,6 +9613,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
         }]
       ]],
       ["locate-path", [
+        ["npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocate-path%2Fdownload%2Flocate-path-2.0.0.tgz", {
+          "packageLocation": "./.yarn/cache/locate-path-npm-2.0.0-2561ff48c2-ee5a888d68.zip/node_modules/locate-path/",
+          "packageDependencies": [
+            ["locate-path", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocate-path%2Fdownload%2Flocate-path-2.0.0.tgz"],
+            ["p-locate", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-2.0.0.tgz"],
+            ["path-exists", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpath-exists%2Fdownload%2Fpath-exists-3.0.0.tgz"]
+          ],
+          "linkType": "HARD",
+        }],
         ["npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocate-path%2Fdownload%2Flocate-path-3.0.0.tgz", {
           "packageLocation": "./.yarn/cache/locate-path-npm-3.0.0-05cc4c2e8a-0b6bf0c1bb.zip/node_modules/locate-path/",
           "packageDependencies": [
@@ -9644,6 +9832,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
         }]
       ]],
       ["memory-fs", [
+        ["npm:0.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fmemory-fs%2Fdownload%2Fmemory-fs-0.2.0.tgz", {
+          "packageLocation": "./.yarn/cache/memory-fs-npm-0.2.0-d4de38f132-373cf2a451.zip/node_modules/memory-fs/",
+          "packageDependencies": [
+            ["memory-fs", "npm:0.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fmemory-fs%2Fdownload%2Fmemory-fs-0.2.0.tgz"]
+          ],
+          "linkType": "HARD",
+        }],
         ["npm:0.4.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fmemory-fs%2Fdownload%2Fmemory-fs-0.4.1.tgz", {
           "packageLocation": "./.yarn/cache/memory-fs-npm-0.4.1-75bd36d5b4-ba79207118.zip/node_modules/memory-fs/",
           "packageDependencies": [
@@ -10221,6 +10416,19 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
           "linkType": "HARD",
         }]
       ]],
+      ["normalize-package-data", [
+        ["npm:2.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fnormalize-package-data%2Fdownload%2Fnormalize-package-data-2.5.0.tgz", {
+          "packageLocation": "./.yarn/cache/normalize-package-data-npm-2.5.0-4d392e3f0a-97d4d6b061.zip/node_modules/normalize-package-data/",
+          "packageDependencies": [
+            ["normalize-package-data", "npm:2.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fnormalize-package-data%2Fdownload%2Fnormalize-package-data-2.5.0.tgz"],
+            ["hosted-git-info", "npm:2.8.8::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhosted-git-info%2Fdownload%2Fhosted-git-info-2.8.8.tgz"],
+            ["resolve", "patch:resolve@npm%3A1.17.0%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Fresolve%252Fdownload%252Fresolve-1.17.0.tgz#builtin<compat/resolve>::version=1.17.0&hash=3388aa"],
+            ["semver", "npm:5.7.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz"],
+            ["validate-npm-package-license", "npm:3.0.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fvalidate-npm-package-license%2Fdownload%2Fvalidate-npm-package-license-3.0.4.tgz"]
+          ],
+          "linkType": "HARD",
+        }]
+      ]],
       ["normalize-path", [
         ["npm:2.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fnormalize-path%2Fdownload%2Fnormalize-path-2.1.1.tgz", {
           "packageLocation": "./.yarn/cache/normalize-path-npm-2.1.1-0182e75f79-9eb82b2f6a.zip/node_modules/normalize-path/",
@@ -10606,6 +10814,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
         }]
       ]],
       ["p-limit", [
+        ["npm:1.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-limit%2Fdownload%2Fp-limit-1.3.0.tgz", {
+          "packageLocation": "./.yarn/cache/p-limit-npm-1.3.0-8733d5eba4-579cbd3d6c.zip/node_modules/p-limit/",
+          "packageDependencies": [
+            ["p-limit", "npm:1.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-limit%2Fdownload%2Fp-limit-1.3.0.tgz"],
+            ["p-try", "npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-try%2Fdownload%2Fp-try-1.0.0.tgz"]
+          ],
+          "linkType": "HARD",
+        }],
         ["npm:2.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-limit%2Fdownload%2Fp-limit-2.3.0.tgz", {
           "packageLocation": "./.yarn/cache/p-limit-npm-2.3.0-1a838d725f-5f20492a25.zip/node_modules/p-limit/",
           "packageDependencies": [
@@ -10624,6 +10840,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
         }]
       ]],
       ["p-locate", [
+        ["npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-2.0.0.tgz", {
+          "packageLocation": "./.yarn/cache/p-locate-npm-2.0.0-d80a803b39-b6dabbd855.zip/node_modules/p-locate/",
+          "packageDependencies": [
+            ["p-locate", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-2.0.0.tgz"],
+            ["p-limit", "npm:1.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-limit%2Fdownload%2Fp-limit-1.3.0.tgz"]
+          ],
+          "linkType": "HARD",
+        }],
         ["npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-3.0.0.tgz", {
           "packageLocation": "./.yarn/cache/p-locate-npm-3.0.0-e428a293a5-3ee9e3ed0b.zip/node_modules/p-locate/",
           "packageDependencies": [
@@ -10669,6 +10893,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
         }]
       ]],
       ["p-try", [
+        ["npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-try%2Fdownload%2Fp-try-1.0.0.tgz", {
+          "packageLocation": "./.yarn/cache/p-try-npm-1.0.0-8c8e61438d-85739d77b3.zip/node_modules/p-try/",
+          "packageDependencies": [
+            ["p-try", "npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-try%2Fdownload%2Fp-try-1.0.0.tgz"]
+          ],
+          "linkType": "HARD",
+        }],
         ["npm:2.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-try%2Fdownload%2Fp-try-2.2.0.tgz", {
           "packageLocation": "./.yarn/cache/p-try-npm-2.2.0-ed6cbde710-20983f3765.zip/node_modules/p-try/",
           "packageDependencies": [
@@ -10735,6 +10966,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
         }]
       ]],
       ["parse-json", [
+        ["npm:2.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse-json%2Fdownload%2Fparse-json-2.2.0.tgz", {
+          "packageLocation": "./.yarn/cache/parse-json-npm-2.2.0-801beb0840-920582196a.zip/node_modules/parse-json/",
+          "packageDependencies": [
+            ["parse-json", "npm:2.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse-json%2Fdownload%2Fparse-json-2.2.0.tgz"],
+            ["error-ex", "npm:1.3.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ferror-ex%2Fdownload%2Ferror-ex-1.3.2.tgz"]
+          ],
+          "linkType": "HARD",
+        }],
         ["npm:4.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse-json%2Fdownload%2Fparse-json-4.0.0.tgz", {
           "packageLocation": "./.yarn/cache/parse-json-npm-4.0.0-8cd06cd604-fa9d23708f.zip/node_modules/parse-json/",
           "packageDependencies": [
@@ -10878,6 +11117,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
         }]
       ]],
       ["path-type", [
+        ["npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpath-type%2Fdownload%2Fpath-type-2.0.0.tgz", {
+          "packageLocation": "./.yarn/cache/path-type-npm-2.0.0-59132af1ec-d028f828df.zip/node_modules/path-type/",
+          "packageDependencies": [
+            ["path-type", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpath-type%2Fdownload%2Fpath-type-2.0.0.tgz"],
+            ["pify", "npm:2.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpify%2Fdownload%2Fpify-2.3.0.tgz"]
+          ],
+          "linkType": "HARD",
+        }],
         ["npm:4.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpath-type%2Fdownload%2Fpath-type-4.0.0.tgz", {
           "packageLocation": "./.yarn/cache/path-type-npm-4.0.0-307bedbdb8-ef5835f2eb.zip/node_modules/path-type/",
           "packageDependencies": [
@@ -10963,6 +11210,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
         }]
       ]],
       ["pkg-dir", [
+        ["npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpkg-dir%2Fdownload%2Fpkg-dir-2.0.0.tgz", {
+          "packageLocation": "./.yarn/cache/pkg-dir-npm-2.0.0-bed7e047e5-f8ae3a1517.zip/node_modules/pkg-dir/",
+          "packageDependencies": [
+            ["pkg-dir", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpkg-dir%2Fdownload%2Fpkg-dir-2.0.0.tgz"],
+            ["find-up", "npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-2.1.0.tgz"]
+          ],
+          "linkType": "HARD",
+        }],
         ["npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpkg-dir%2Fdownload%2Fpkg-dir-3.0.0.tgz", {
           "packageLocation": "./.yarn/cache/pkg-dir-npm-3.0.0-0903fcee43-f29a7d0134.zip/node_modules/pkg-dir/",
           "packageDependencies": [
@@ -12094,6 +12349,29 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
           "linkType": "HARD",
         }]
       ]],
+      ["read-pkg", [
+        ["npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fread-pkg%2Fdownload%2Fread-pkg-2.0.0.tgz", {
+          "packageLocation": "./.yarn/cache/read-pkg-npm-2.0.0-33997d44e1-ddf911317f.zip/node_modules/read-pkg/",
+          "packageDependencies": [
+            ["read-pkg", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fread-pkg%2Fdownload%2Fread-pkg-2.0.0.tgz"],
+            ["load-json-file", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fload-json-file%2Fdownload%2Fload-json-file-2.0.0.tgz"],
+            ["normalize-package-data", "npm:2.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fnormalize-package-data%2Fdownload%2Fnormalize-package-data-2.5.0.tgz"],
+            ["path-type", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpath-type%2Fdownload%2Fpath-type-2.0.0.tgz"]
+          ],
+          "linkType": "HARD",
+        }]
+      ]],
+      ["read-pkg-up", [
+        ["npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fread-pkg-up%2Fdownload%2Fread-pkg-up-2.0.0.tgz", {
+          "packageLocation": "./.yarn/cache/read-pkg-up-npm-2.0.0-bf8b4f9d8a-f35e4cb457.zip/node_modules/read-pkg-up/",
+          "packageDependencies": [
+            ["read-pkg-up", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fread-pkg-up%2Fdownload%2Fread-pkg-up-2.0.0.tgz"],
+            ["find-up", "npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-2.1.0.tgz"],
+            ["read-pkg", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fread-pkg%2Fdownload%2Fread-pkg-2.0.0.tgz"]
+          ],
+          "linkType": "HARD",
+        }]
+      ]],
       ["readable-stream", [
         ["npm:2.3.7::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freadable-stream%2Fdownload%2Freadable-stream-2.3.7.tgz", {
           "packageLocation": "./.yarn/cache/readable-stream-npm-2.3.7-f79a45df7e-6e38265606.zip/node_modules/readable-stream/",
@@ -13135,6 +13413,46 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
           "linkType": "HARD",
         }]
       ]],
+      ["spdx-correct", [
+        ["npm:3.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-correct%2Fdownload%2Fspdx-correct-3.1.1.tgz", {
+          "packageLocation": "./.yarn/cache/spdx-correct-npm-3.1.1-f3740410f8-f3413eb225.zip/node_modules/spdx-correct/",
+          "packageDependencies": [
+            ["spdx-correct", "npm:3.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-correct%2Fdownload%2Fspdx-correct-3.1.1.tgz"],
+            ["spdx-expression-parse", "npm:3.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-expression-parse%2Fdownload%2Fspdx-expression-parse-3.0.1.tgz"],
+            ["spdx-license-ids", "npm:3.0.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-license-ids%2Fdownload%2Fspdx-license-ids-3.0.5.tgz"]
+          ],
+          "linkType": "HARD",
+        }]
+      ]],
+      ["spdx-exceptions", [
+        ["npm:2.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-exceptions%2Fdownload%2Fspdx-exceptions-2.3.0.tgz", {
+          "packageLocation": "./.yarn/cache/spdx-exceptions-npm-2.3.0-b9d007563f-3cbd249889.zip/node_modules/spdx-exceptions/",
+          "packageDependencies": [
+            ["spdx-exceptions", "npm:2.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-exceptions%2Fdownload%2Fspdx-exceptions-2.3.0.tgz"]
+          ],
+          "linkType": "HARD",
+        }]
+      ]],
+      ["spdx-expression-parse", [
+        ["npm:3.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-expression-parse%2Fdownload%2Fspdx-expression-parse-3.0.1.tgz", {
+          "packageLocation": "./.yarn/cache/spdx-expression-parse-npm-3.0.1-e386dadbb9-f0211cada3.zip/node_modules/spdx-expression-parse/",
+          "packageDependencies": [
+            ["spdx-expression-parse", "npm:3.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-expression-parse%2Fdownload%2Fspdx-expression-parse-3.0.1.tgz"],
+            ["spdx-exceptions", "npm:2.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-exceptions%2Fdownload%2Fspdx-exceptions-2.3.0.tgz"],
+            ["spdx-license-ids", "npm:3.0.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-license-ids%2Fdownload%2Fspdx-license-ids-3.0.5.tgz"]
+          ],
+          "linkType": "HARD",
+        }]
+      ]],
+      ["spdx-license-ids", [
+        ["npm:3.0.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-license-ids%2Fdownload%2Fspdx-license-ids-3.0.5.tgz", {
+          "packageLocation": "./.yarn/cache/spdx-license-ids-npm-3.0.5-d72e7a737e-4ff7c0615a.zip/node_modules/spdx-license-ids/",
+          "packageDependencies": [
+            ["spdx-license-ids", "npm:3.0.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-license-ids%2Fdownload%2Fspdx-license-ids-3.0.5.tgz"]
+          ],
+          "linkType": "HARD",
+        }]
+      ]],
       ["spdy", [
         ["npm:4.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdy%2Fdownload%2Fspdy-4.0.2.tgz", {
           "packageLocation": "./.yarn/cache/spdy-npm-4.0.2-c75dcd93ce-388d39324d.zip/node_modules/spdy/",
@@ -13439,6 +13757,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
           "linkType": "HARD",
         }]
       ]],
+      ["strip-bom", [
+        ["npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-bom%2Fdownload%2Fstrip-bom-3.0.0.tgz", {
+          "packageLocation": "./.yarn/cache/strip-bom-npm-3.0.0-ed0d0bfd30-361dd1dd08.zip/node_modules/strip-bom/",
+          "packageDependencies": [
+            ["strip-bom", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-bom%2Fdownload%2Fstrip-bom-3.0.0.tgz"]
+          ],
+          "linkType": "HARD",
+        }]
+      ]],
       ["strip-comments", [
         ["npm:1.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-comments%2Fdownload%2Fstrip-comments-1.0.2.tgz", {
           "packageLocation": "./.yarn/cache/strip-comments-npm-1.0.2-f0a6d3bb12-21d667d3ba.zip/node_modules/strip-comments/",
@@ -13530,6 +13857,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
         }]
       ]],
       ["tapable", [
+        ["npm:0.1.10::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftapable%2Fdownload%2Ftapable-0.1.10.tgz", {
+          "packageLocation": "./.yarn/cache/tapable-npm-0.1.10-47dee951fe-5604e1127d.zip/node_modules/tapable/",
+          "packageDependencies": [
+            ["tapable", "npm:0.1.10::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftapable%2Fdownload%2Ftapable-0.1.10.tgz"]
+          ],
+          "linkType": "HARD",
+        }],
         ["npm:1.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftapable%2Fdownload%2Ftapable-1.1.3.tgz", {
           "packageLocation": "./.yarn/cache/tapable-npm-1.1.3-5d1594602f-b2c2ab2026.zip/node_modules/tapable/",
           "packageDependencies": [
@@ -13695,6 +14029,8 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
             ["css-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.2.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-loader%2Fdownload%2Fcss-loader-4.2.1.tgz"],
             ["eslint", "npm:7.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.7.0.tgz"],
             ["eslint-config-prettier", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:6.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-config-prettier%2Fdownload%2Feslint-config-prettier-6.11.0.tgz"],
+            ["eslint-import-resolver-webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:0.12.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-import-resolver-webpack%2Fdownload%2Feslint-import-resolver-webpack-0.12.2.tgz"],
+            ["eslint-plugin-import", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:2.22.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-import%2Fdownload%2Feslint-plugin-import-2.22.0.tgz"],
             ["eslint-plugin-prettier", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.1.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-prettier%2Fdownload%2Feslint-plugin-prettier-3.1.4.tgz"],
             ["eslint-plugin-react", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.20.6::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-react%2Fdownload%2Feslint-plugin-react-7.20.6.tgz"],
             ["eslint-plugin-react-hooks", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-react-hooks%2Fdownload%2Feslint-plugin-react-hooks-4.1.0.tgz"],
@@ -13888,6 +14224,19 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
           "linkType": "HARD",
         }]
       ]],
+      ["tsconfig-paths", [
+        ["npm:3.9.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsconfig-paths%2Fdownload%2Ftsconfig-paths-3.9.0.tgz", {
+          "packageLocation": "./.yarn/cache/tsconfig-paths-npm-3.9.0-39cafa29c9-5383ba626b.zip/node_modules/tsconfig-paths/",
+          "packageDependencies": [
+            ["tsconfig-paths", "npm:3.9.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsconfig-paths%2Fdownload%2Ftsconfig-paths-3.9.0.tgz"],
+            ["@types/json5", "npm:0.0.29::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fjson5%2Fdownload%2F%40types%2Fjson5-0.0.29.tgz"],
+            ["json5", "npm:1.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson5%2Fdownload%2Fjson5-1.0.1.tgz"],
+            ["minimist", "npm:1.2.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fminimist%2Fdownload%2Fminimist-1.2.5.tgz"],
+            ["strip-bom", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-bom%2Fdownload%2Fstrip-bom-3.0.0.tgz"]
+          ],
+          "linkType": "HARD",
+        }]
+      ]],
       ["tslib", [
         ["npm:1.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftslib%2Fdownload%2Ftslib-1.13.0.tgz", {
           "packageLocation": "./.yarn/cache/tslib-npm-1.13.0-630f8c4e72-5dc3bdaea3.zip/node_modules/tslib/",
@@ -14322,6 +14671,17 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
           "linkType": "HARD",
         }]
       ]],
+      ["validate-npm-package-license", [
+        ["npm:3.0.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fvalidate-npm-package-license%2Fdownload%2Fvalidate-npm-package-license-3.0.4.tgz", {
+          "packageLocation": "./.yarn/cache/validate-npm-package-license-npm-3.0.4-f515d7a10c-940899bd4e.zip/node_modules/validate-npm-package-license/",
+          "packageDependencies": [
+            ["validate-npm-package-license", "npm:3.0.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fvalidate-npm-package-license%2Fdownload%2Fvalidate-npm-package-license-3.0.4.tgz"],
+            ["spdx-correct", "npm:3.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-correct%2Fdownload%2Fspdx-correct-3.1.1.tgz"],
+            ["spdx-expression-parse", "npm:3.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-expression-parse%2Fdownload%2Fspdx-expression-parse-3.0.1.tgz"]
+          ],
+          "linkType": "HARD",
+        }]
+      ]],
       ["value-equal", [
         ["npm:1.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fvalue-equal%2Fdownload%2Fvalue-equal-1.0.1.tgz", {
           "packageLocation": "./.yarn/cache/value-equal-npm-1.0.1-ce12345615-ae8cc7bbb2.zip/node_modules/value-equal/",
diff --git a/Timeline/ClientApp/package.json b/Timeline/ClientApp/package.json
index a2f6e051..b633630b 100644
--- a/Timeline/ClientApp/package.json
+++ b/Timeline/ClientApp/package.json
@@ -86,6 +86,8 @@
     "css-loader": "^4.2.1",
     "eslint": "^7.7.0",
     "eslint-config-prettier": "^6.11.0",
+    "eslint-import-resolver-webpack": "^0.12.2",
+    "eslint-plugin-import": "^2.22.0",
     "eslint-plugin-prettier": "^3.1.4",
     "eslint-plugin-react": "^7.20.6",
     "eslint-plugin-react-hooks": "^4.1.0",
diff --git a/Timeline/ClientApp/src/app/App.tsx b/Timeline/ClientApp/src/app/App.tsx
index 7b382c2f..74deddda 100644
--- a/Timeline/ClientApp/src/app/App.tsx
+++ b/Timeline/ClientApp/src/app/App.tsx
@@ -11,7 +11,6 @@ import About from "./about/About";
 import User from "./user/User";
 import TimelinePage from "./timeline/TimelinePage";
 import AlertHost from "./common/AlertHost";
-
 import { dataStorage } from "./data/common";
 import { userService, useRawUser } from "./data/user";
 
diff --git a/Timeline/ClientApp/src/app/about/About.tsx b/Timeline/ClientApp/src/app/about/About.tsx
index 751fca14..519eef18 100644
--- a/Timeline/ClientApp/src/app/about/About.tsx
+++ b/Timeline/ClientApp/src/app/about/About.tsx
@@ -1,11 +1,11 @@
 import React from "react";
 import { useTranslation, Trans } from "react-i18next";
 
+import AppBar from "../common/AppBar";
+
 import authorAvatarUrl from "./author-avatar.png";
 import githubLogoUrl from "./github.png";
 
-import AppBar from "../common/AppBar";
-
 const frontendCredits: {
   name: string;
   url: string;
diff --git a/Timeline/ClientApp/src/app/admin/Admin.tsx b/Timeline/ClientApp/src/app/admin/Admin.tsx
index 2f8b2c05..e2f71091 100644
--- a/Timeline/ClientApp/src/app/admin/Admin.tsx
+++ b/Timeline/ClientApp/src/app/admin/Admin.tsx
@@ -10,10 +10,10 @@ import {
 import classnames from "classnames";
 
 import AppBar from "../common/AppBar";
-import UserAdmin from "./UserAdmin";
-
 import { UserWithToken } from "../data/user";
 
+import UserAdmin from "./UserAdmin";
+
 interface AdminProps {
   user: UserWithToken;
 }
diff --git a/Timeline/ClientApp/src/app/admin/UserAdmin.tsx b/Timeline/ClientApp/src/app/admin/UserAdmin.tsx
index 57eed455..1bf3bda1 100644
--- a/Timeline/ClientApp/src/app/admin/UserAdmin.tsx
+++ b/Timeline/ClientApp/src/app/admin/UserAdmin.tsx
@@ -13,7 +13,6 @@ import {
 import axios from "axios";
 
 import OperationDialog from "../common/OperationDialog";
-
 import { User, UserWithToken } from "../data/user";
 
 const apiBaseUrl = "/api";
diff --git a/Timeline/ClientApp/src/app/common/AlertHost.tsx b/Timeline/ClientApp/src/app/common/AlertHost.tsx
index e22354fa..bfcf5c00 100644
--- a/Timeline/ClientApp/src/app/common/AlertHost.tsx
+++ b/Timeline/ClientApp/src/app/common/AlertHost.tsx
@@ -2,6 +2,7 @@ import React, { useCallback } from "react";
 import { Alert } from "reactstrap";
 import without from "lodash/without";
 import concat from "lodash/concat";
+import { useTranslation } from "react-i18next";
 
 import {
   alertService,
@@ -9,7 +10,6 @@ import {
   kAlertHostId,
   AlertInfo,
 } from "./alert-service";
-import { useTranslation } from "react-i18next";
 
 interface AutoCloseAlertProps {
   alert: AlertInfo;
@@ -56,7 +56,7 @@ interface AlertInfoExEx extends AlertInfoEx {
   close: () => void;
 }
 
-export const AlertHost: React.FC = () => {
+const AlertHost: React.FC = () => {
   const [alerts, setAlerts] = React.useState<AlertInfoExEx[]>([]);
 
   // react guarantee that state setters are stable, so we don't need to add it to dependency list
diff --git a/Timeline/ClientApp/src/app/data/timeline.ts b/Timeline/ClientApp/src/app/data/timeline.ts
index ed6cffd6..8e8860a3 100644
--- a/Timeline/ClientApp/src/app/data/timeline.ts
+++ b/Timeline/ClientApp/src/app/data/timeline.ts
@@ -5,16 +5,6 @@ import { map, switchMap, startWith } from "rxjs/operators";
 import { uniqBy } from "lodash";
 
 import { convertError } from "../utilities/rxjs";
-
-import { dataStorage, throwIfNotNetworkError, BlobOrStatus } from "./common";
-import { DataHub, WithSyncStatus } from "./DataHub";
-
-import { UserAuthInfo, checkLogin, userService, userInfoService } from "./user";
-
-export { kTimelineVisibilities } from "../http/timeline";
-
-export type { TimelineVisibility } from "../http/timeline";
-
 import {
   TimelineVisibility,
   HttpTimelineInfo,
@@ -32,6 +22,14 @@ import {
 import { BlobWithEtag, NotModified, HttpForbiddenError } from "../http/common";
 import { HttpUser } from "../http/user";
 
+import { dataStorage, throwIfNotNetworkError, BlobOrStatus } from "./common";
+import { DataHub, WithSyncStatus } from "./DataHub";
+import { UserAuthInfo, checkLogin, userService, userInfoService } from "./user";
+
+export { kTimelineVisibilities } from "../http/timeline";
+
+export type { TimelineVisibility } from "../http/timeline";
+
 export type TimelineInfo = HttpTimelineInfo;
 export type TimelineChangePropertyRequest = HttpTimelinePatchRequest;
 export type TimelineCreatePostRequest = HttpTimelinePostPostRequest;
diff --git a/Timeline/ClientApp/src/app/data/user.ts b/Timeline/ClientApp/src/app/data/user.ts
index 8aee0c5f..ceabdbe2 100644
--- a/Timeline/ClientApp/src/app/data/user.ts
+++ b/Timeline/ClientApp/src/app/data/user.ts
@@ -5,10 +5,6 @@ import { map, filter } from "rxjs/operators";
 import { UiLogicError } from "../common";
 import { convertError } from "../utilities/rxjs";
 import { pushAlert } from "../common/alert-service";
-
-import { dataStorage, throwIfNotNetworkError } from "./common";
-import { DataHub } from "./DataHub";
-
 import { HttpNetworkError, BlobWithEtag, NotModified } from "../http/common";
 import {
   getHttpTokenClient,
@@ -20,6 +16,9 @@ import {
   HttpUser,
 } from "../http/user";
 
+import { DataHub } from "./DataHub";
+import { dataStorage, throwIfNotNetworkError } from "./common";
+
 export type User = HttpUser;
 
 export interface UserAuthInfo {
diff --git a/Timeline/ClientApp/src/app/home/BoardWithUser.tsx b/Timeline/ClientApp/src/app/home/BoardWithUser.tsx
index 4910aebe..22a4667c 100644
--- a/Timeline/ClientApp/src/app/home/BoardWithUser.tsx
+++ b/Timeline/ClientApp/src/app/home/BoardWithUser.tsx
@@ -4,7 +4,6 @@ import { useTranslation } from "react-i18next";
 
 import { UserWithToken } from "../data/user";
 import { TimelineInfo } from "../data/timeline";
-
 import { getHttpTimelineClient } from "../http/timeline";
 
 import TimelineBoard from "./TimelineBoard";
diff --git a/Timeline/ClientApp/src/app/home/BoardWithoutUser.tsx b/Timeline/ClientApp/src/app/home/BoardWithoutUser.tsx
index a7dc36be..972c1b25 100644
--- a/Timeline/ClientApp/src/app/home/BoardWithoutUser.tsx
+++ b/Timeline/ClientApp/src/app/home/BoardWithoutUser.tsx
@@ -2,7 +2,6 @@ import React from "react";
 import { Row, Col } from "reactstrap";
 
 import { TimelineInfo } from "../data/timeline";
-
 import { getHttpTimelineClient } from "../http/timeline";
 
 import TimelineBoard from "./TimelineBoard";
diff --git a/Timeline/ClientApp/src/app/home/Home.tsx b/Timeline/ClientApp/src/app/home/Home.tsx
index 00e6ff5a..910c9a01 100644
--- a/Timeline/ClientApp/src/app/home/Home.tsx
+++ b/Timeline/ClientApp/src/app/home/Home.tsx
@@ -4,9 +4,9 @@ import { Row, Container, Button, Col } from "reactstrap";
 import { useTranslation } from "react-i18next";
 
 import { useUser } from "../data/user";
-
 import AppBar from "../common/AppBar";
 import SearchInput from "../common/SearchInput";
+
 import BoardWithoutUser from "./BoardWithoutUser";
 import BoardWithUser from "./BoardWithUser";
 import TimelineCreateDialog from "./TimelineCreateDialog";
diff --git a/Timeline/ClientApp/src/app/home/OfflineBoard.tsx b/Timeline/ClientApp/src/app/home/OfflineBoard.tsx
index 458166ac..fbd37efd 100644
--- a/Timeline/ClientApp/src/app/home/OfflineBoard.tsx
+++ b/Timeline/ClientApp/src/app/home/OfflineBoard.tsx
@@ -3,7 +3,6 @@ import { Link } from "react-router-dom";
 import { Trans } from "react-i18next";
 
 import { getAllCachedTimelineNames } from "../data/timeline";
-
 import UserTimelineLogo from "../common/UserTimelineLogo";
 import TimelineLogo from "../common/TimelineLogo";
 
diff --git a/Timeline/ClientApp/src/app/home/TimelineBoard.tsx b/Timeline/ClientApp/src/app/home/TimelineBoard.tsx
index 91bf2b77..21dcac3f 100644
--- a/Timeline/ClientApp/src/app/home/TimelineBoard.tsx
+++ b/Timeline/ClientApp/src/app/home/TimelineBoard.tsx
@@ -5,7 +5,6 @@ import { Spinner } from "reactstrap";
 import { Trans } from "react-i18next";
 
 import { TimelineInfo } from "../data/timeline";
-
 import TimelineLogo from "../common/TimelineLogo";
 import UserTimelineLogo from "../common/UserTimelineLogo";
 
diff --git a/Timeline/ClientApp/src/app/home/TimelineCreateDialog.tsx b/Timeline/ClientApp/src/app/home/TimelineCreateDialog.tsx
index c5ba64e7..911dd60c 100644
--- a/Timeline/ClientApp/src/app/home/TimelineCreateDialog.tsx
+++ b/Timeline/ClientApp/src/app/home/TimelineCreateDialog.tsx
@@ -2,7 +2,6 @@ import React from "react";
 import { useHistory } from "react-router";
 
 import { validateTimelineName, timelineService } from "../data/timeline";
-
 import OperationDialog from "../common/OperationDialog";
 
 interface TimelineCreateDialogProps {
diff --git a/Timeline/ClientApp/src/app/http/mock/user.ts b/Timeline/ClientApp/src/app/http/mock/user.ts
index 1ecd7365..7948da11 100644
--- a/Timeline/ClientApp/src/app/http/mock/user.ts
+++ b/Timeline/ClientApp/src/app/http/mock/user.ts
@@ -10,7 +10,6 @@ import {
 } from "../user";
 
 import { mockStorage, sha1, mockPrepare } from "./common";
-
 import defaultAvatarUrl from "./default-avatar.png";
 
 let _defaultAvatar: BlobWithEtag | undefined = undefined;
diff --git a/Timeline/ClientApp/src/app/http/timeline.ts b/Timeline/ClientApp/src/app/http/timeline.ts
index 4a325bca..a9511c64 100644
--- a/Timeline/ClientApp/src/app/http/timeline.ts
+++ b/Timeline/ClientApp/src/app/http/timeline.ts
@@ -1,6 +1,7 @@
 import axios, { AxiosError } from "axios";
 
 import { updateQueryString, applyQueryParameters } from "../utilities/url";
+
 import {
   apiBaseUrl,
   extractResponseData,
diff --git a/Timeline/ClientApp/src/app/settings/Settings.tsx b/Timeline/ClientApp/src/app/settings/Settings.tsx
index dd648538..64851ce2 100644
--- a/Timeline/ClientApp/src/app/settings/Settings.tsx
+++ b/Timeline/ClientApp/src/app/settings/Settings.tsx
@@ -14,7 +14,6 @@ import {
 } from "reactstrap";
 
 import { useUser, userService } from "../data/user";
-
 import AppBar from "../common/AppBar";
 import OperationDialog, {
   OperationInputErrorInfo,
diff --git a/Timeline/ClientApp/src/app/timeline/TimelineInfoCard.tsx b/Timeline/ClientApp/src/app/timeline/TimelineInfoCard.tsx
index 3591b6f9..c11c3376 100644
--- a/Timeline/ClientApp/src/app/timeline/TimelineInfoCard.tsx
+++ b/Timeline/ClientApp/src/app/timeline/TimelineInfoCard.tsx
@@ -12,9 +12,9 @@ import { fromEvent } from "rxjs";
 
 import { useAvatar } from "../data/user";
 import { timelineVisibilityTooltipTranslationMap } from "../data/timeline";
+import BlobImage from "../common/BlobImage";
 
 import { TimelineCardComponentProps } from "./TimelinePageTemplateUI";
-import BlobImage from "../common/BlobImage";
 
 export type OrdinaryTimelineManageItem = "delete";
 
diff --git a/Timeline/ClientApp/src/app/timeline/TimelineItem.tsx b/Timeline/ClientApp/src/app/timeline/TimelineItem.tsx
index 0d62b0e7..33f0741e 100644
--- a/Timeline/ClientApp/src/app/timeline/TimelineItem.tsx
+++ b/Timeline/ClientApp/src/app/timeline/TimelineItem.tsx
@@ -12,12 +12,10 @@ import {
 import { Link } from "react-router-dom";
 import { useTranslation } from "react-i18next";
 import Svg from "react-inlinesvg";
-
 import chevronDownIcon from "bootstrap-icons/icons/chevron-down.svg";
 import trashIcon from "bootstrap-icons/icons/trash.svg";
 
 import BlobImage from "../common/BlobImage";
-
 import { useAvatar } from "../data/user";
 import { TimelinePostInfo } from "../data/timeline";
 
diff --git a/Timeline/ClientApp/src/app/timeline/TimelineMember.tsx b/Timeline/ClientApp/src/app/timeline/TimelineMember.tsx
index 559750d2..f334c6e9 100644
--- a/Timeline/ClientApp/src/app/timeline/TimelineMember.tsx
+++ b/Timeline/ClientApp/src/app/timeline/TimelineMember.tsx
@@ -11,7 +11,6 @@ import {
 } from "reactstrap";
 
 import { User, useAvatar } from "../data/user";
-
 import SearchInput from "../common/SearchInput";
 import BlobImage from "../common/BlobImage";
 
diff --git a/Timeline/ClientApp/src/app/timeline/TimelinePage.tsx b/Timeline/ClientApp/src/app/timeline/TimelinePage.tsx
index 0771b40e..21d52db1 100644
--- a/Timeline/ClientApp/src/app/timeline/TimelinePage.tsx
+++ b/Timeline/ClientApp/src/app/timeline/TimelinePage.tsx
@@ -1,8 +1,9 @@
 import React from "react";
 import { useParams } from "react-router";
 
-import TimelinePageUI from "./TimelinePageUI";
 import TimelinePageTemplate from "../timeline/TimelinePageTemplate";
+
+import TimelinePageUI from "./TimelinePageUI";
 import { OrdinaryTimelineManageItem } from "./TimelineInfoCard";
 import TimelineDeleteDialog from "./TimelineDeleteDialog";
 
diff --git a/Timeline/ClientApp/src/app/timeline/TimelinePageTemplate.tsx b/Timeline/ClientApp/src/app/timeline/TimelinePageTemplate.tsx
index be96a09e..3f470826 100644
--- a/Timeline/ClientApp/src/app/timeline/TimelinePageTemplate.tsx
+++ b/Timeline/ClientApp/src/app/timeline/TimelinePageTemplate.tsx
@@ -11,13 +11,13 @@ import {
   usePostList,
   useTimelineInfo,
 } from "../data/timeline";
+import { UiLogicError } from "../common";
 
 import { TimelineDeleteCallback } from "./Timeline";
 import { TimelineMemberDialog } from "./TimelineMember";
 import TimelinePropertyChangeDialog from "./TimelinePropertyChangeDialog";
 import { TimelinePageTemplateUIProps } from "./TimelinePageTemplateUI";
 import { TimelinePostSendCallback } from "./TimelinePostEdit";
-import { UiLogicError } from "../common";
 
 export interface TimelinePageTemplateProps<TManageItem> {
   name: string;
diff --git a/Timeline/ClientApp/src/app/timeline/TimelinePageTemplateUI.tsx b/Timeline/ClientApp/src/app/timeline/TimelinePageTemplateUI.tsx
index 2066ceb1..e6514478 100644
--- a/Timeline/ClientApp/src/app/timeline/TimelinePageTemplateUI.tsx
+++ b/Timeline/ClientApp/src/app/timeline/TimelinePageTemplateUI.tsx
@@ -4,7 +4,6 @@ import { useTranslation } from "react-i18next";
 import { fromEvent } from "rxjs";
 import Svg from "react-inlinesvg";
 import clsx from "clsx";
-
 import arrowsAngleContractIcon from "bootstrap-icons/icons/arrows-angle-contract.svg";
 import arrowsAngleExpandIcon from "bootstrap-icons/icons/arrows-angle-expand.svg";
 
@@ -16,12 +15,12 @@ import {
   timelineService,
 } from "../data/timeline";
 import { userService } from "../data/user";
+import AppBar from "../common/AppBar";
 
 import Timeline, {
   TimelinePostInfoEx,
   TimelineDeleteCallback,
 } from "./Timeline";
-import AppBar from "../common/AppBar";
 import TimelinePostEdit, { TimelinePostSendCallback } from "./TimelinePostEdit";
 
 type TimelinePostSyncState = "syncing" | "synced" | "offline";
diff --git a/Timeline/ClientApp/src/app/timeline/TimelinePostEdit.tsx b/Timeline/ClientApp/src/app/timeline/TimelinePostEdit.tsx
index 151df40a..b30dc8d3 100644
--- a/Timeline/ClientApp/src/app/timeline/TimelinePostEdit.tsx
+++ b/Timeline/ClientApp/src/app/timeline/TimelinePostEdit.tsx
@@ -2,13 +2,11 @@ import React from "react";
 import { Button, Spinner, Row, Col } from "reactstrap";
 import { useTranslation } from "react-i18next";
 import Svg from "react-inlinesvg";
-
 import textIcon from "bootstrap-icons/icons/card-text.svg";
 import imageIcon from "bootstrap-icons/icons/image.svg";
 
 import { pushAlert } from "../common/alert-service";
 import { TimelineCreatePostRequest } from "../data/timeline";
-
 import FileInput from "../common/FileInput";
 import { UiLogicError } from "../common";
 
diff --git a/Timeline/ClientApp/src/app/timeline/TimelinePropertyChangeDialog.tsx b/Timeline/ClientApp/src/app/timeline/TimelinePropertyChangeDialog.tsx
index a0eea775..bb0e3ea2 100644
--- a/Timeline/ClientApp/src/app/timeline/TimelinePropertyChangeDialog.tsx
+++ b/Timeline/ClientApp/src/app/timeline/TimelinePropertyChangeDialog.tsx
@@ -5,7 +5,6 @@ import {
   kTimelineVisibilities,
   TimelineChangePropertyRequest,
 } from "../data/timeline";
-
 import OperationDialog, {
   OperationSelectInputInfoOption,
 } from "../common/OperationDialog";
diff --git a/Timeline/ClientApp/src/app/user/Login.tsx b/Timeline/ClientApp/src/app/user/Login.tsx
index 4f9cd05d..db6c43c4 100644
--- a/Timeline/ClientApp/src/app/user/Login.tsx
+++ b/Timeline/ClientApp/src/app/user/Login.tsx
@@ -1,10 +1,6 @@
 import React, { Fragment, useState, useEffect } from "react";
 import { useHistory } from "react-router";
 import { useTranslation } from "react-i18next";
-
-import AppBar from "../common/AppBar";
-
-import { useUser, userService } from "../data/user";
 import {
   Label,
   FormGroup,
@@ -15,6 +11,9 @@ import {
   Button,
 } from "reactstrap";
 
+import AppBar from "../common/AppBar";
+import { useUser, userService } from "../data/user";
+
 const Login: React.FC = (_) => {
   const { t } = useTranslation();
   const history = useHistory();
diff --git a/Timeline/ClientApp/src/app/user/User.tsx b/Timeline/ClientApp/src/app/user/User.tsx
index 6f61cacf..56058ce7 100644
--- a/Timeline/ClientApp/src/app/user/User.tsx
+++ b/Timeline/ClientApp/src/app/user/User.tsx
@@ -3,12 +3,12 @@ import { useParams } from "react-router";
 
 import { UiLogicError } from "../common";
 import { useUser, userInfoService } from "../data/user";
-import { changeNickname } from "./api";
+import TimelinePageTemplate from "../timeline/TimelinePageTemplate";
 
+import { changeNickname } from "./api";
 import UserPage from "./UserPage";
 import ChangeNicknameDialog from "./ChangeNicknameDialog";
 import ChangeAvatarDialog from "./ChangeAvatarDialog";
-import TimelinePageTemplate from "../timeline/TimelinePageTemplate";
 import { PersonalTimelineManageItem } from "./UserInfoCard";
 
 const User: React.FC = (_) => {
diff --git a/Timeline/ClientApp/src/app/user/UserInfoCard.tsx b/Timeline/ClientApp/src/app/user/UserInfoCard.tsx
index 9ce46e3c..d6e648cc 100644
--- a/Timeline/ClientApp/src/app/user/UserInfoCard.tsx
+++ b/Timeline/ClientApp/src/app/user/UserInfoCard.tsx
@@ -12,7 +12,6 @@ import { fromEvent } from "rxjs";
 
 import { timelineVisibilityTooltipTranslationMap } from "../data/timeline";
 import { useAvatar } from "../data/user";
-
 import { TimelineCardComponentProps } from "../timeline/TimelinePageTemplateUI";
 import BlobImage from "../common/BlobImage";
 
diff --git a/Timeline/ClientApp/src/app/user/UserPage.tsx b/Timeline/ClientApp/src/app/user/UserPage.tsx
index 42f174d9..ab498f30 100644
--- a/Timeline/ClientApp/src/app/user/UserPage.tsx
+++ b/Timeline/ClientApp/src/app/user/UserPage.tsx
@@ -1,10 +1,10 @@
 import React from "react";
 
 import { ExcludeKey } from "../utilities/type";
-
 import TimelinePageTemplateUI, {
   TimelinePageTemplateUIProps,
 } from "../timeline/TimelinePageTemplateUI";
+
 import UserInfoCard, { PersonalTimelineManageItem } from "./UserInfoCard";
 
 export type UserPageProps = ExcludeKey<
diff --git a/Timeline/ClientApp/yarn.lock b/Timeline/ClientApp/yarn.lock
index c5ddde3b..8562343a 100644
--- a/Timeline/ClientApp/yarn.lock
+++ b/Timeline/ClientApp/yarn.lock
@@ -1835,6 +1835,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@types/json5@npm:^0.0.29":
+  version: 0.0.29
+  resolution: "@types/json5@npm:0.0.29::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fjson5%2Fdownload%2F%40types%2Fjson5-0.0.29.tgz"
+  checksum: 66e9ac0143ec521522c7bb670301e9836ee886207eeed1aab6d4854a1b19b404ab3a54cd8d449f9b1f13acc357f540be96f8ac2d1e86e301eab52ae0f9a4066f
+  languageName: node
+  linkType: hard
+
 "@types/keyv@npm:*":
   version: 3.1.1
   resolution: "@types/keyv@npm:3.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fkeyv%2Fdownload%2F%40types%2Fkeyv-3.1.1.tgz"
@@ -2679,6 +2686,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"array-find@npm:^1.0.0":
+  version: 1.0.0
+  resolution: "array-find@npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-find%2Fdownload%2Farray-find-1.0.0.tgz"
+  checksum: 1f6f5270a3e4a02324815e732a66ef962becaf69d064e45d8377c023a29cec5abd7236e2fe00036fdf622c0ce178649d78fd83452464644f78c346d6336c1d6c
+  languageName: node
+  linkType: hard
+
 "array-flatten@npm:1.1.1":
   version: 1.1.1
   resolution: "array-flatten@npm:1.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-flatten%2Fdownload%2Farray-flatten-1.1.1.tgz"
@@ -2734,6 +2748,16 @@ __metadata:
   languageName: node
   linkType: hard
 
+"array.prototype.flat@npm:^1.2.3":
+  version: 1.2.3
+  resolution: "array.prototype.flat@npm:1.2.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray.prototype.flat%2Fdownload%2Farray.prototype.flat-1.2.3.tgz"
+  dependencies:
+    define-properties: ^1.1.3
+    es-abstract: ^1.17.0-next.1
+  checksum: f88a474d1cb3bfb2cfa44a5d36047bad146324f1beabbc743689d34fa36f29fab277008446ab56601c48721e1d50c5f47e5b3fae2583cc3724d1e6073cbdd901
+  languageName: node
+  linkType: hard
+
 "array.prototype.flatmap@npm:^1.2.3":
   version: 1.2.3
   resolution: "array.prototype.flatmap@npm:1.2.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray.prototype.flatmap%2Fdownload%2Farray.prototype.flatmap-1.2.3.tgz"
@@ -3949,6 +3973,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"contains-path@npm:^0.1.0":
+  version: 0.1.0
+  resolution: "contains-path@npm:0.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcontains-path%2Fdownload%2Fcontains-path-0.1.0.tgz"
+  checksum: 59920a59a0c7d1244235d76b8cfd2b2e7a8dcc463fa578ef9d4d5a5a73eeb14d75dada6b21188e0b35f2474ae9efd10c3698372e674db9c6a904b281998b97d6
+  languageName: node
+  linkType: hard
+
 "content-disposition@npm:0.5.3":
   version: 0.5.3
   resolution: "content-disposition@npm:0.5.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcontent-disposition%2Fdownload%2Fcontent-disposition-0.5.3.tgz"
@@ -4332,7 +4363,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"debug@npm:2.6.9, debug@npm:^2.2.0, debug@npm:^2.3.3, debug@npm:^2.6.8":
+"debug@npm:2.6.9, debug@npm:^2.2.0, debug@npm:^2.3.3, debug@npm:^2.6.8, debug@npm:^2.6.9":
   version: 2.6.9
   resolution: "debug@npm:2.6.9::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz"
   dependencies:
@@ -4598,6 +4629,16 @@ __metadata:
   languageName: node
   linkType: hard
 
+"doctrine@npm:1.5.0":
+  version: 1.5.0
+  resolution: "doctrine@npm:1.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdoctrine%2Fdownload%2Fdoctrine-1.5.0.tgz"
+  dependencies:
+    esutils: ^2.0.2
+    isarray: ^1.0.0
+  checksum: aaffea02f963b8b07a78b1e27d7cef29be65d31be2c6681cb2872c2fb3781e14615bd05d4dff6036f75dcf3f191216058409fbfec805d3a7277a8647cd5bdee1
+  languageName: node
+  linkType: hard
+
 "doctrine@npm:^2.1.0":
   version: 2.1.0
   resolution: "doctrine@npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdoctrine%2Fdownload%2Fdoctrine-2.1.0.tgz"
@@ -4829,6 +4870,17 @@ __metadata:
   languageName: node
   linkType: hard
 
+"enhanced-resolve@npm:^0.9.1":
+  version: 0.9.1
+  resolution: "enhanced-resolve@npm:0.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fenhanced-resolve%2Fdownload%2Fenhanced-resolve-0.9.1.tgz"
+  dependencies:
+    graceful-fs: ^4.1.2
+    memory-fs: ^0.2.0
+    tapable: ^0.1.8
+  checksum: c814cd928250e8c0133132e9557ca96f125dcfe974ec8a9818c08deb0d1f280b5ad0f5a3cb74b63be1af029f1d1584f51fa11ce355e944d42d7c543b7795f8fb
+  languageName: node
+  linkType: hard
+
 "enhanced-resolve@npm:^4.0.0, enhanced-resolve@npm:^4.1.1, enhanced-resolve@npm:^4.3.0":
   version: 4.3.0
   resolution: "enhanced-resolve@npm:4.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fenhanced-resolve%2Fdownload%2Fenhanced-resolve-4.3.0.tgz"
@@ -4881,7 +4933,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"error-ex@npm:^1.3.1":
+"error-ex@npm:^1.2.0, error-ex@npm:^1.3.1":
   version: 1.3.2
   resolution: "error-ex@npm:1.3.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ferror-ex%2Fdownload%2Ferror-ex-1.3.2.tgz"
   dependencies:
@@ -4954,6 +5006,70 @@ __metadata:
   languageName: node
   linkType: hard
 
+"eslint-import-resolver-node@npm:^0.3.3":
+  version: 0.3.4
+  resolution: "eslint-import-resolver-node@npm:0.3.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-import-resolver-node%2Fdownload%2Feslint-import-resolver-node-0.3.4.tgz"
+  dependencies:
+    debug: ^2.6.9
+    resolve: ^1.13.1
+  checksum: 825e34e662c988ece8229e6956a95f12d2fa19265b429e3e3db14e58bfe72e270c999cda0cfc690793ed6e6a3e49ffa8df0e0a8842d668a1f0f7de5ae1aa36f9
+  languageName: node
+  linkType: hard
+
+"eslint-import-resolver-webpack@npm:^0.12.2":
+  version: 0.12.2
+  resolution: "eslint-import-resolver-webpack@npm:0.12.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-import-resolver-webpack%2Fdownload%2Feslint-import-resolver-webpack-0.12.2.tgz"
+  dependencies:
+    array-find: ^1.0.0
+    debug: ^2.6.9
+    enhanced-resolve: ^0.9.1
+    find-root: ^1.1.0
+    has: ^1.0.3
+    interpret: ^1.2.0
+    lodash: ^4.17.15
+    node-libs-browser: ^1.0.0 || ^2.0.0
+    resolve: ^1.13.1
+    semver: ^5.7.1
+  peerDependencies:
+    eslint-plugin-import: ">=1.4.0"
+    webpack: ">=1.11.0"
+  checksum: 5310d4383e443387b45e2ea2371b9e0725812b7cb996fa5be9f0e9c4e0716fa9fa1aebadd85def4067fced274e68479d23a4e4397e4277e5acb64793da6d30b6
+  languageName: node
+  linkType: hard
+
+"eslint-module-utils@npm:^2.6.0":
+  version: 2.6.0
+  resolution: "eslint-module-utils@npm:2.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-module-utils%2Fdownload%2Feslint-module-utils-2.6.0.tgz"
+  dependencies:
+    debug: ^2.6.9
+    pkg-dir: ^2.0.0
+  checksum: f584af176480a702eedcdb3f610797f8b8d1293c3835ed71fadb579ec28400b91ded5283729418f63d48dc27c6358bd66f2bd839614d565a1b78d3c3440ee8f7
+  languageName: node
+  linkType: hard
+
+"eslint-plugin-import@npm:^2.22.0":
+  version: 2.22.0
+  resolution: "eslint-plugin-import@npm:2.22.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-import%2Fdownload%2Feslint-plugin-import-2.22.0.tgz"
+  dependencies:
+    array-includes: ^3.1.1
+    array.prototype.flat: ^1.2.3
+    contains-path: ^0.1.0
+    debug: ^2.6.9
+    doctrine: 1.5.0
+    eslint-import-resolver-node: ^0.3.3
+    eslint-module-utils: ^2.6.0
+    has: ^1.0.3
+    minimatch: ^3.0.4
+    object.values: ^1.1.1
+    read-pkg-up: ^2.0.0
+    resolve: ^1.17.0
+    tsconfig-paths: ^3.9.0
+  peerDependencies:
+    eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0
+  checksum: ad41aec63d8986e0a0e279bb2877e1f36029573b8f310112159509fd52d7344a2e91bd4bb9c6d2b131838a3538a0bc5e3998217df1b88304df9872ad9fb30c84
+  languageName: node
+  linkType: hard
+
 "eslint-plugin-prettier@npm:^3.1.4":
   version: 3.1.4
   resolution: "eslint-plugin-prettier@npm:3.1.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-prettier%2Fdownload%2Feslint-plugin-prettier-3.1.4.tgz"
@@ -5488,6 +5604,22 @@ __metadata:
   languageName: node
   linkType: hard
 
+"find-root@npm:^1.1.0":
+  version: 1.1.0
+  resolution: "find-root@npm:1.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-root%2Fdownload%2Ffind-root-1.1.0.tgz"
+  checksum: 34f9eeb7258b3b5e270824a11bae4a8e6075efe79a319c034a3c5cae90cdb558c524c42ff7938b1200f648349c9dc04e860c8eaef852c802f5a1c26fa04d5ab1
+  languageName: node
+  linkType: hard
+
+"find-up@npm:^2.0.0, find-up@npm:^2.1.0":
+  version: 2.1.0
+  resolution: "find-up@npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-2.1.0.tgz"
+  dependencies:
+    locate-path: ^2.0.0
+  checksum: 9dedb89f936b572f7c9fda3f66ebe146b0000fe9ef16fad94a77c25ce9585962e910bb32c1e08bab9b423985ff20221d2af4b7e4130b27c0f5f60c1aad3f6a7f
+  languageName: node
+  linkType: hard
+
 "find-up@npm:^3.0.0":
   version: 3.0.0
   resolution: "find-up@npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-3.0.0.tgz"
@@ -6188,6 +6320,13 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
+"hosted-git-info@npm:^2.1.4":
+  version: 2.8.8
+  resolution: "hosted-git-info@npm:2.8.8::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhosted-git-info%2Fdownload%2Fhosted-git-info-2.8.8.tgz"
+  checksum: 3ecc389dc6ecbd5463fada7e04461e96f3c817fe2f989ca41e9dd3b503745a0bfa26fba405861b2831ca64edc1abc5d2fbc97ee977303f89650dac4fbfdc2d7a
+  languageName: node
+  linkType: hard
+
 "hpack.js@npm:^2.1.6":
   version: 2.1.6
   resolution: "hpack.js@npm:2.1.6::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhpack.js%2Fdownload%2Fhpack.js-2.1.6.tgz"
@@ -6605,7 +6744,7 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
-"interpret@npm:^1.4.0":
+"interpret@npm:^1.2.0, interpret@npm:^1.4.0":
   version: 1.4.0
   resolution: "interpret@npm:1.4.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Finterpret%2Fdownload%2Finterpret-1.4.0.tgz"
   checksum: f15725d76206525546f559030ddc967db025c6db904eb8798a70ec3c07e42c5537c5cbc73a15eafd4ae5cdabad35601abf8878261c03dcc8217747e8037575fe
@@ -7282,6 +7421,18 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
+"load-json-file@npm:^2.0.0":
+  version: 2.0.0
+  resolution: "load-json-file@npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fload-json-file%2Fdownload%2Fload-json-file-2.0.0.tgz"
+  dependencies:
+    graceful-fs: ^4.1.2
+    parse-json: ^2.2.0
+    pify: ^2.0.0
+    strip-bom: ^3.0.0
+  checksum: c6ea93d36099dd6e778c6c018c9e184ad65d278a9538c2280f959b040b1a9a756d8856bdaf8a38c8f1454eca19bf4798ea59f79ccd8bb1c33aa8b7ecbe157f0c
+  languageName: node
+  linkType: hard
+
 "loader-runner@npm:^2.4.0":
   version: 2.4.0
   resolution: "loader-runner@npm:2.4.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-runner%2Fdownload%2Floader-runner-2.4.0.tgz"
@@ -7320,6 +7471,16 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
+"locate-path@npm:^2.0.0":
+  version: 2.0.0
+  resolution: "locate-path@npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocate-path%2Fdownload%2Flocate-path-2.0.0.tgz"
+  dependencies:
+    p-locate: ^2.0.0
+    path-exists: ^3.0.0
+  checksum: ee5a888d686f8d555ebfa6c4f6f3b7c5cdfa5f382dee17e0b3fde7456fc68301ddb6a79790a412659d1e067f2f58fd74c683b203fc20368deaed45fb985b4fda
+  languageName: node
+  linkType: hard
+
 "locate-path@npm:^3.0.0":
   version: 3.0.0
   resolution: "locate-path@npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocate-path%2Fdownload%2Flocate-path-3.0.0.tgz"
@@ -7511,6 +7672,13 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
+"memory-fs@npm:^0.2.0":
+  version: 0.2.0
+  resolution: "memory-fs@npm:0.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fmemory-fs%2Fdownload%2Fmemory-fs-0.2.0.tgz"
+  checksum: 373cf2a451883983f904df0074fce05951f92a45f927be32312d192208657d3e0f69688017c1f9571abbc0c554301bc4f925825cb1cd15f558d3a22e02c789d0
+  languageName: node
+  linkType: hard
+
 "memory-fs@npm:^0.4.1":
   version: 0.4.1
   resolution: "memory-fs@npm:0.4.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fmemory-fs%2Fdownload%2Fmemory-fs-0.4.1.tgz"
@@ -7976,7 +8144,7 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
-"node-libs-browser@npm:^2.2.1":
+"node-libs-browser@npm:^1.0.0 || ^2.0.0, node-libs-browser@npm:^2.2.1":
   version: 2.2.1
   resolution: "node-libs-browser@npm:2.2.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-libs-browser%2Fdownload%2Fnode-libs-browser-2.2.1.tgz"
   dependencies:
@@ -8043,6 +8211,18 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
+"normalize-package-data@npm:^2.3.2":
+  version: 2.5.0
+  resolution: "normalize-package-data@npm:2.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fnormalize-package-data%2Fdownload%2Fnormalize-package-data-2.5.0.tgz"
+  dependencies:
+    hosted-git-info: ^2.1.4
+    resolve: ^1.10.0
+    semver: 2 || 3 || 4 || 5
+    validate-npm-package-license: ^3.0.1
+  checksum: 97d4d6b061cab51425ddb05c38d126d7a1a2a6f2c9949bef2b5ad7ef19c005df12099ea442e4cb09190929b7770008f94f87b10342a66f739acf92a7ebb9d9f2
+  languageName: node
+  linkType: hard
+
 "normalize-path@npm:^2.1.1":
   version: 2.1.1
   resolution: "normalize-path@npm:2.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fnormalize-path%2Fdownload%2Fnormalize-path-2.1.1.tgz"
@@ -8380,6 +8560,15 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
+"p-limit@npm:^1.1.0":
+  version: 1.3.0
+  resolution: "p-limit@npm:1.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-limit%2Fdownload%2Fp-limit-1.3.0.tgz"
+  dependencies:
+    p-try: ^1.0.0
+  checksum: 579cbd3d6c606058aa624c464e2cb3c4b56d04ed4cbafdb705633cbe62ba36d77ba2c4289023335ba382f4fbf32c15709465eea18a0e1547c5ebc4b887f2a7da
+  languageName: node
+  linkType: hard
+
 "p-limit@npm:^2.0.0, p-limit@npm:^2.2.0":
   version: 2.3.0
   resolution: "p-limit@npm:2.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-limit%2Fdownload%2Fp-limit-2.3.0.tgz"
@@ -8398,6 +8587,15 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
+"p-locate@npm:^2.0.0":
+  version: 2.0.0
+  resolution: "p-locate@npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-2.0.0.tgz"
+  dependencies:
+    p-limit: ^1.1.0
+  checksum: b6dabbd855fba9bfa74b77882f96d0eac6c25d9966e61ab0ed7bf3d19f2e3b766f290ded1aada1ac4ce2627217b00342cf7a1d36482bada59ba6789be412dad7
+  languageName: node
+  linkType: hard
+
 "p-locate@npm:^3.0.0":
   version: 3.0.0
   resolution: "p-locate@npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-3.0.0.tgz"
@@ -8441,6 +8639,13 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
+"p-try@npm:^1.0.0":
+  version: 1.0.0
+  resolution: "p-try@npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-try%2Fdownload%2Fp-try-1.0.0.tgz"
+  checksum: 85739d77b3e9f6a52a8545f1adc53621fb5df4d6ef9b59a3f54f3f3159b45c4100d4e63128a1e790e9ff8ff8b86213ace314ff6d2d327c3edcceea18891baa42
+  languageName: node
+  linkType: hard
+
 "p-try@npm:^2.0.0":
   version: 2.2.0
   resolution: "p-try@npm:2.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-try%2Fdownload%2Fp-try-2.2.0.tgz"
@@ -8499,6 +8704,15 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
+"parse-json@npm:^2.2.0":
+  version: 2.2.0
+  resolution: "parse-json@npm:2.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse-json%2Fdownload%2Fparse-json-2.2.0.tgz"
+  dependencies:
+    error-ex: ^1.2.0
+  checksum: 920582196a8edebb3d3c4623b2f057987218272b35ae4d2d310c00bc1bd7e89b87c79358d7e009d54f047ca2eea82eab8d7e1b14e1f7cbbb345ef29fcda29731
+  languageName: node
+  linkType: hard
+
 "parse-json@npm:^4.0.0":
   version: 4.0.0
   resolution: "parse-json@npm:4.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse-json%2Fdownload%2Fparse-json-4.0.0.tgz"
@@ -8619,6 +8833,15 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
+"path-type@npm:^2.0.0":
+  version: 2.0.0
+  resolution: "path-type@npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpath-type%2Fdownload%2Fpath-type-2.0.0.tgz"
+  dependencies:
+    pify: ^2.0.0
+  checksum: d028f828dffe48a0062dc4370d5118a0c45f5fb075b013a1dfb13eadd1426eba0c8c2a13fa78f19fc4fd8771ef2012e9d062f8f970c8e56df36d4fbbe5073b26
+  languageName: node
+  linkType: hard
+
 "path-type@npm:^4.0.0":
   version: 4.0.0
   resolution: "path-type@npm:4.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpath-type%2Fdownload%2Fpath-type-4.0.0.tgz"
@@ -8690,6 +8913,15 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
+"pkg-dir@npm:^2.0.0":
+  version: 2.0.0
+  resolution: "pkg-dir@npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpkg-dir%2Fdownload%2Fpkg-dir-2.0.0.tgz"
+  dependencies:
+    find-up: ^2.1.0
+  checksum: f8ae3a151714c61283aeb24385b10355a238732fab822a560145c670c21350da2024f01918231222bcdfce53ec5d69056681be2c2cffe3f3a06e462b9ef2ac29
+  languageName: node
+  linkType: hard
+
 "pkg-dir@npm:^3.0.0":
   version: 3.0.0
   resolution: "pkg-dir@npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpkg-dir%2Fdownload%2Fpkg-dir-3.0.0.tgz"
@@ -9688,6 +9920,27 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
+"read-pkg-up@npm:^2.0.0":
+  version: 2.0.0
+  resolution: "read-pkg-up@npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fread-pkg-up%2Fdownload%2Fread-pkg-up-2.0.0.tgz"
+  dependencies:
+    find-up: ^2.0.0
+    read-pkg: ^2.0.0
+  checksum: f35e4cb4577b994fc9497886672c748de766ab034e24f029111b6bbbfe757b2e27b6d2b82a28a38f45d9d89ea8a9b1d3c04854e5f991d5deed48f4c9ff7baeb9
+  languageName: node
+  linkType: hard
+
+"read-pkg@npm:^2.0.0":
+  version: 2.0.0
+  resolution: "read-pkg@npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fread-pkg%2Fdownload%2Fread-pkg-2.0.0.tgz"
+  dependencies:
+    load-json-file: ^2.0.0
+    normalize-package-data: ^2.3.2
+    path-type: ^2.0.0
+  checksum: ddf911317fba54abb447b1d76dd1785c37e1360f7b1e39d83201f6f3807572391ab7392f11727a9c4d90600ebc6616d22e72514d2291688c89ebd440148840b4
+  languageName: node
+  linkType: hard
+
 "readable-stream@npm:1 || 2, readable-stream@npm:^2.0.0, readable-stream@npm:^2.0.1, readable-stream@npm:^2.0.2, readable-stream@npm:^2.0.6, readable-stream@npm:^2.1.5, readable-stream@npm:^2.2.2, readable-stream@npm:^2.3.3, readable-stream@npm:^2.3.6, readable-stream@npm:~2.3.6":
   version: 2.3.7
   resolution: "readable-stream@npm:2.3.7::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freadable-stream%2Fdownload%2Freadable-stream-2.3.7.tgz"
@@ -9983,7 +10236,7 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
-"resolve@^1.14.2, resolve@^1.17.0, resolve@^1.3.2":
+"resolve@^1.10.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.3.2":
   version: 1.17.0
   resolution: "resolve@npm:1.17.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fresolve%2Fdownload%2Fresolve-1.17.0.tgz"
   dependencies:
@@ -9992,7 +10245,7 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
-"resolve@patch:resolve@^1.14.2#builtin<compat/resolve>, resolve@patch:resolve@^1.17.0#builtin<compat/resolve>, resolve@patch:resolve@^1.3.2#builtin<compat/resolve>":
+"resolve@patch:resolve@^1.10.0#builtin<compat/resolve>, resolve@patch:resolve@^1.13.1#builtin<compat/resolve>, resolve@patch:resolve@^1.14.2#builtin<compat/resolve>, resolve@patch:resolve@^1.17.0#builtin<compat/resolve>, resolve@patch:resolve@^1.3.2#builtin<compat/resolve>":
   version: 1.17.0
   resolution: "resolve@patch:resolve@npm%3A1.17.0%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Fresolve%252Fdownload%252Fresolve-1.17.0.tgz#builtin<compat/resolve>::version=1.17.0&hash=3388aa"
   dependencies:
@@ -10270,6 +10523,15 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
+"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.4.1, semver@npm:^5.5.0, semver@npm:^5.6.0, semver@npm:^5.7.1":
+  version: 5.7.1
+  resolution: "semver@npm:5.7.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz"
+  bin:
+    semver: ./bin/semver
+  checksum: 06ff0ed753ebf741b7602be8faad620d6e160a2cb3f61019d00d919c8bca141638aa23c34da779b8595afdc9faa3678bfbb5f60366b6a4f65f98cf86605bbcdb
+  languageName: node
+  linkType: hard
+
 "semver@npm:7.0.0":
   version: 7.0.0
   resolution: "semver@npm:7.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-7.0.0.tgz"
@@ -10279,15 +10541,6 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
-"semver@npm:^5.4.1, semver@npm:^5.5.0, semver@npm:^5.6.0":
-  version: 5.7.1
-  resolution: "semver@npm:5.7.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz"
-  bin:
-    semver: ./bin/semver
-  checksum: 06ff0ed753ebf741b7602be8faad620d6e160a2cb3f61019d00d919c8bca141638aa23c34da779b8595afdc9faa3678bfbb5f60366b6a4f65f98cf86605bbcdb
-  languageName: node
-  linkType: hard
-
 "semver@npm:^6.0.0, semver@npm:^6.3.0":
   version: 6.3.0
   resolution: "semver@npm:6.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-6.3.0.tgz"
@@ -10647,6 +10900,40 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
+"spdx-correct@npm:^3.0.0":
+  version: 3.1.1
+  resolution: "spdx-correct@npm:3.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-correct%2Fdownload%2Fspdx-correct-3.1.1.tgz"
+  dependencies:
+    spdx-expression-parse: ^3.0.0
+    spdx-license-ids: ^3.0.0
+  checksum: f3413eb225ef9f13aa2ec05230ff7669bffad055a7f62ec85164dd27f00a9f1e19880554a8fa5350fc434764ff895836c207f98813511a0180b0e929581bfe01
+  languageName: node
+  linkType: hard
+
+"spdx-exceptions@npm:^2.1.0":
+  version: 2.3.0
+  resolution: "spdx-exceptions@npm:2.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-exceptions%2Fdownload%2Fspdx-exceptions-2.3.0.tgz"
+  checksum: 3cbd2498897dc384158666a9dd7435e3b42ece5da42fd967b218b790e248381d001ec77a676d13d1f4e8da317d97b7bc0ebf4fff37bfbb95923d49b024030c96
+  languageName: node
+  linkType: hard
+
+"spdx-expression-parse@npm:^3.0.0":
+  version: 3.0.1
+  resolution: "spdx-expression-parse@npm:3.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-expression-parse%2Fdownload%2Fspdx-expression-parse-3.0.1.tgz"
+  dependencies:
+    spdx-exceptions: ^2.1.0
+    spdx-license-ids: ^3.0.0
+  checksum: f0211cada3fa7cd9db2243143fb0e66e28a46d72d8268f38ad2196aac49408d87892cda6e5600d43d6b05ed2707cb2f4148deb27b092aafabc50a67038f4cbf5
+  languageName: node
+  linkType: hard
+
+"spdx-license-ids@npm:^3.0.0":
+  version: 3.0.5
+  resolution: "spdx-license-ids@npm:3.0.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-license-ids%2Fdownload%2Fspdx-license-ids-3.0.5.tgz"
+  checksum: 4ff7c0615a3c69a195b206a425e6a633ccb24e680ac21f5464b249b57ebb5c3f356f84a8e713599758be69ee4a849319d7fce7041b69e29acd9d31daed3fb8eb
+  languageName: node
+  linkType: hard
+
 "spdy-transport@npm:^3.0.0":
   version: 3.0.0
   resolution: "spdy-transport@npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdy-transport%2Fdownload%2Fspdy-transport-3.0.0.tgz"
@@ -10932,6 +11219,13 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
+"strip-bom@npm:^3.0.0":
+  version: 3.0.0
+  resolution: "strip-bom@npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-bom%2Fdownload%2Fstrip-bom-3.0.0.tgz"
+  checksum: 361dd1dd08ae626940061570d20bcf73909d0459734b8880eb3d14176aa28f41cf85d13af036c323ce739e04ef3930a71b516950c5985b318bae3757ecb2974c
+  languageName: node
+  linkType: hard
+
 "strip-comments@npm:^1.0.2":
   version: 1.0.2
   resolution: "strip-comments@npm:1.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-comments%2Fdownload%2Fstrip-comments-1.0.2.tgz"
@@ -11014,6 +11308,13 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
+"tapable@npm:^0.1.8":
+  version: 0.1.10
+  resolution: "tapable@npm:0.1.10::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftapable%2Fdownload%2Ftapable-0.1.10.tgz"
+  checksum: 5604e1127dbfaa9da431121c947be751e0a91fe21f6256da03b61d1c8c5111b6434806ff751758ec07b810ff2c4e538829aad417e55e6b9b4a73544747eca43e
+  languageName: node
+  linkType: hard
+
 "tapable@npm:^1.0.0, tapable@npm:^1.1.3":
   version: 1.1.3
   resolution: "tapable@npm:1.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftapable%2Fdownload%2Ftapable-1.1.3.tgz"
@@ -11167,6 +11468,8 @@ fsevents@~2.1.2:
     css-loader: ^4.2.1
     eslint: ^7.7.0
     eslint-config-prettier: ^6.11.0
+    eslint-import-resolver-webpack: ^0.12.2
+    eslint-plugin-import: ^2.22.0
     eslint-plugin-prettier: ^3.1.4
     eslint-plugin-react: ^7.20.6
     eslint-plugin-react-hooks: ^4.1.0
@@ -11341,6 +11644,18 @@ fsevents@~2.1.2:
   languageName: node
   linkType: hard
 
+"tsconfig-paths@npm:^3.9.0":
+  version: 3.9.0
+  resolution: "tsconfig-paths@npm:3.9.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsconfig-paths%2Fdownload%2Ftsconfig-paths-3.9.0.tgz"
+  dependencies:
+    "@types/json5": ^0.0.29
+    json5: ^1.0.1
+    minimist: ^1.2.0
+    strip-bom: ^3.0.0
+  checksum: 5383ba626b3ac70e08094b9dfd1e30ce82878407b6c8db8cd84279cc7c7340d5f53f67dbeb8174a233c082a068322a6b00ec8514b96d9a80a453e0476dc116d2
+  languageName: node
+  linkType: hard
+
 "tslib@npm:^1.10.0, tslib@npm:^1.13.0, tslib@npm:^1.8.1, tslib@npm:^1.9.0":
   version: 1.13.0
   resolution: "tslib@npm:1.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftslib%2Fdownload%2Ftslib-1.13.0.tgz"
@@ -11712,6 +12027,16 @@ typescript@^4.0.2:
   languageName: node
   linkType: hard
 
+"validate-npm-package-license@npm:^3.0.1":
+  version: 3.0.4
+  resolution: "validate-npm-package-license@npm:3.0.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fvalidate-npm-package-license%2Fdownload%2Fvalidate-npm-package-license-3.0.4.tgz"
+  dependencies:
+    spdx-correct: ^3.0.0
+    spdx-expression-parse: ^3.0.0
+  checksum: 940899bd4eacfa012ceecb10a5814ba0e8103da5243aa74d0d62f1f8a405efcd23e034fb7193e2d05b392870c53aabcb1f66439b062075cdcb28bc5d562a8ff6
+  languageName: node
+  linkType: hard
+
 "value-equal@npm:^1.0.1":
   version: 1.0.1
   resolution: "value-equal@npm:1.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fvalue-equal%2Fdownload%2Fvalue-equal-1.0.1.tgz"
-- 
cgit v1.2.3

