diff options
author | crupest <crupest@outlook.com> | 2020-08-24 22:59:45 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2020-08-24 22:59:45 +0800 |
commit | cc0cc154b9506d1961d08cb29fbc29ad815bad69 (patch) | |
tree | a50e492d784a553c4fb7bc016819f872c2382247 | |
parent | 13cf2ab0598adb291066ef64a7b377909ef58525 (diff) | |
download | timeline-cc0cc154b9506d1961d08cb29fbc29ad815bad69.tar.gz timeline-cc0cc154b9506d1961d08cb29fbc29ad815bad69.tar.bz2 timeline-cc0cc154b9506d1961d08cb29fbc29ad815bad69.zip |
...
84 files changed, 11660 insertions, 10351 deletions
diff --git a/Timeline/ClientApp/.eslintrc.js b/Timeline/ClientApp/.eslintrc.js index 3cbc1cb6..2013f23d 100644 --- a/Timeline/ClientApp/.eslintrc.js +++ b/Timeline/ClientApp/.eslintrc.js @@ -9,7 +9,7 @@ module.exports = { 'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
- 'prettier',
+ 'plugin:prettier/recommended',
'prettier/react',
'prettier/@typescript-eslint',
'plugin:react-hooks/recommended',
diff --git a/Timeline/ClientApp/.pnp.js b/Timeline/ClientApp/.pnp.js index 06cec550..4b0d0ff5 100644 --- a/Timeline/ClientApp/.pnp.js +++ b/Timeline/ClientApp/.pnp.js @@ -31,7 +31,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "fallbackPool": [
[
"@babel/core",
- "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"
+ "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"
],
[
"@babel/plugin-proposal-class-properties",
@@ -47,7 +47,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],
[
"@babel/plugin-proposal-optional-chaining",
- "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-chaining%2Fdownload%2F%40babel%2Fplugin-proposal-optional-chaining-7.10.4.tgz"
+ "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-chaining%2Fdownload%2F%40babel%2Fplugin-proposal-optional-chaining-7.11.0.tgz"
],
[
"@babel/plugin-syntax-dynamic-import",
@@ -55,7 +55,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],
[
"@babel/preset-env",
- "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-env%2Fdownload%2F%40babel%2Fpreset-env-7.10.4.tgz"
+ "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-env%2Fdownload%2F%40babel%2Fpreset-env-7.11.0.tgz"
],
[
"@babel/preset-react",
@@ -79,15 +79,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],
[
"@types/lodash",
- "npm:4.14.157::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Flodash%2Fdownload%2F%40types%2Flodash-4.14.157.tgz"
+ "npm:4.14.159::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Flodash%2Fdownload%2F%40types%2Flodash-4.14.159.tgz"
],
[
"@types/node",
- "npm:14.0.23::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-14.0.23.tgz"
+ "npm:14.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-14.6.0.tgz"
],
[
"@types/react",
- "npm:16.9.43::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact%2Fdownload%2F%40types%2Freact-16.9.43.tgz"
+ "npm:16.9.46::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact%2Fdownload%2F%40types%2Freact-16.9.46.tgz"
],
[
"@types/react-dom",
@@ -107,7 +107,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],
[
"@types/reactstrap",
- "npm:8.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freactstrap%2Fdownload%2F%40types%2Freactstrap-8.5.0.tgz"
+ "npm:8.5.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freactstrap%2Fdownload%2F%40types%2Freactstrap-8.5.1.tgz"
],
[
"@types/webpack-env",
@@ -119,11 +119,11 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],
[
"@typescript-eslint/eslint-plugin",
- "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Feslint-plugin%2Fdownload%2F%40typescript-eslint%2Feslint-plugin-3.6.1.tgz"
+ "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Feslint-plugin%2Fdownload%2F%40typescript-eslint%2Feslint-plugin-3.9.1.tgz"
],
[
"@typescript-eslint/parser",
- "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fparser%2Fdownload%2F%40typescript-eslint%2Fparser-3.6.1.tgz"
+ "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fparser%2Fdownload%2F%40typescript-eslint%2Fparser-3.9.1.tgz"
],
[
"@yarnpkg/pnpify",
@@ -131,7 +131,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],
[
"axios",
- "npm:0.19.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.19.2.tgz"
+ "npm:0.20.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.20.0.tgz"
],
[
"babel-loader",
@@ -143,7 +143,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],
[
"bootstrap",
- "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbootstrap%2Fdownload%2Fbootstrap-4.5.0.tgz"
+ "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.5.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbootstrap%2Fdownload%2Fbootstrap-4.5.2.tgz"
],
[
"bootstrap-icons",
@@ -175,11 +175,11 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],
[
"css-loader",
- "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-loader%2Fdownload%2Fcss-loader-3.6.0.tgz"
+ "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.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.5.0.tgz"
+ "npm:7.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.7.0.tgz"
],
[
"eslint-config-prettier",
@@ -191,11 +191,11 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],
[
"eslint-plugin-react",
- "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.20.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-react%2Fdownload%2Feslint-plugin-react-7.20.3.tgz"
+ "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.0.8::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-react-hooks%2Fdownload%2Feslint-plugin-react-hooks-4.0.8.tgz"
+ "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"
],
[
"file-loader",
@@ -203,7 +203,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],
[
"html-webpack-plugin",
- "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-webpack-plugin%2Fdownload%2Fhtml-webpack-plugin-3.2.0.tgz"
+ "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-webpack-plugin%2Fdownload%2Fhtml-webpack-plugin-4.3.0.tgz"
],
[
"http-server",
@@ -211,19 +211,19 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],
[
"i18next",
- "npm:19.6.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next%2Fdownload%2Fi18next-19.6.2.tgz"
+ "npm:19.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next%2Fdownload%2Fi18next-19.7.0.tgz"
],
[
"i18next-browser-languagedetector",
- "npm:5.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next-browser-languagedetector%2Fdownload%2Fi18next-browser-languagedetector-5.0.0.tgz"
+ "npm:6.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next-browser-languagedetector%2Fdownload%2Fi18next-browser-languagedetector-6.0.1.tgz"
],
[
"localforage",
- "npm:1.7.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocalforage%2Fdownload%2Flocalforage-1.7.4.tgz"
+ "npm:1.9.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocalforage%2Fdownload%2Flocalforage-1.9.0.tgz"
],
[
"lodash",
- "npm:4.17.19::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.19.tgz"
+ "npm:4.17.20::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.20.tgz"
],
[
"mini-css-extract-plugin",
@@ -247,7 +247,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],
[
"prettier",
- "npm:2.0.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-2.0.5.tgz"
+ "npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-2.1.0.tgz"
],
[
"react",
@@ -263,7 +263,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],
[
"react-i18next",
- "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:11.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-i18next%2Fdownload%2Freact-i18next-11.7.0.tgz"
+ "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:11.7.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-i18next%2Fdownload%2Freact-i18next-11.7.1.tgz"
],
[
"react-inlinesvg",
@@ -287,11 +287,11 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],
[
"regenerator-runtime",
- "npm:0.13.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.13.5.tgz"
+ "npm:0.13.7::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.13.7.tgz"
],
[
"rxjs",
- "npm:6.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Frxjs%2Fdownload%2Frxjs-6.6.0.tgz"
+ "npm:6.6.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Frxjs%2Fdownload%2Frxjs-6.6.2.tgz"
],
[
"sass",
@@ -299,7 +299,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],
[
"sass-loader",
- "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:9.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsass-loader%2Fdownload%2Fsass-loader-9.0.2.tgz"
+ "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:9.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsass-loader%2Fdownload%2Fsass-loader-9.0.3.tgz"
],
[
"style-loader",
@@ -307,11 +307,11 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],
[
"ts-loader",
- "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:8.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fts-loader%2Fdownload%2Fts-loader-8.0.1.tgz"
+ "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:8.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fts-loader%2Fdownload%2Fts-loader-8.0.3.tgz"
],
[
"typescript",
- "patch:typescript@npm%3A3.9.7%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-3.9.7.tgz#builtin<compat/typescript>::version=3.9.7&hash=5b02a2"
+ "patch:typescript@npm%3A4.0.2%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-4.0.2.tgz#builtin<compat/typescript>::version=4.0.2&hash=5b02a2"
],
[
"url-loader",
@@ -319,7 +319,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],
[
"webpack",
- "npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz"
+ "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"
],
[
"webpack-chain",
@@ -365,35 +365,35 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { [null, {
"packageLocation": "./",
"packageDependencies": [
- ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
["@babel/plugin-proposal-class-properties", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-class-properties%2Fdownload%2F%40babel%2Fplugin-proposal-class-properties-7.10.4.tgz"],
["@babel/plugin-proposal-decorators", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-decorators%2Fdownload%2F%40babel%2Fplugin-proposal-decorators-7.10.5.tgz"],
["@babel/plugin-proposal-nullish-coalescing-operator", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator%2Fdownload%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator-7.10.4.tgz"],
- ["@babel/plugin-proposal-optional-chaining", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-chaining%2Fdownload%2F%40babel%2Fplugin-proposal-optional-chaining-7.10.4.tgz"],
+ ["@babel/plugin-proposal-optional-chaining", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-chaining%2Fdownload%2F%40babel%2Fplugin-proposal-optional-chaining-7.11.0.tgz"],
["@babel/plugin-syntax-dynamic-import", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-dynamic-import%2Fdownload%2F%40babel%2Fplugin-syntax-dynamic-import-7.8.3.tgz"],
- ["@babel/preset-env", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-env%2Fdownload%2F%40babel%2Fpreset-env-7.10.4.tgz"],
+ ["@babel/preset-env", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-env%2Fdownload%2F%40babel%2Fpreset-env-7.11.0.tgz"],
["@babel/preset-react", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-react%2Fdownload%2F%40babel%2Fpreset-react-7.10.4.tgz"],
["@babel/preset-typescript", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-typescript%2Fdownload%2F%40babel%2Fpreset-typescript-7.10.4.tgz"],
["@hot-loader/react-dom", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:16.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40hot-loader%2Freact-dom%2Fdownload%2F%40hot-loader%2Freact-dom-16.13.0.tgz"],
["@types/classnames", "npm:2.2.10::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fclassnames%2Fdownload%2F%40types%2Fclassnames-2.2.10.tgz"],
["@types/crypto-js", "npm:3.1.47::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fcrypto-js%2Fdownload%2F%40types%2Fcrypto-js-3.1.47.tgz"],
- ["@types/lodash", "npm:4.14.157::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Flodash%2Fdownload%2F%40types%2Flodash-4.14.157.tgz"],
- ["@types/node", "npm:14.0.23::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-14.0.23.tgz"],
- ["@types/react", "npm:16.9.43::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact%2Fdownload%2F%40types%2Freact-16.9.43.tgz"],
+ ["@types/lodash", "npm:4.14.159::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Flodash%2Fdownload%2F%40types%2Flodash-4.14.159.tgz"],
+ ["@types/node", "npm:14.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-14.6.0.tgz"],
+ ["@types/react", "npm:16.9.46::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact%2Fdownload%2F%40types%2Freact-16.9.46.tgz"],
["@types/react-dom", "npm:16.9.8::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact-dom%2Fdownload%2F%40types%2Freact-dom-16.9.8.tgz"],
["@types/react-responsive", "npm:8.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact-responsive%2Fdownload%2F%40types%2Freact-responsive-8.0.2.tgz"],
["@types/react-router", "npm:5.1.8::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact-router%2Fdownload%2F%40types%2Freact-router-5.1.8.tgz"],
["@types/react-router-dom", "npm:5.1.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact-router-dom%2Fdownload%2F%40types%2Freact-router-dom-5.1.5.tgz"],
- ["@types/reactstrap", "npm:8.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freactstrap%2Fdownload%2F%40types%2Freactstrap-8.5.0.tgz"],
+ ["@types/reactstrap", "npm:8.5.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freactstrap%2Fdownload%2F%40types%2Freactstrap-8.5.1.tgz"],
["@types/webpack-env", "npm:1.15.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fwebpack-env%2Fdownload%2F%40types%2Fwebpack-env-1.15.2.tgz"],
["@types/xregexp", "npm:4.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fxregexp%2Fdownload%2F%40types%2Fxregexp-4.3.0.tgz"],
- ["@typescript-eslint/eslint-plugin", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Feslint-plugin%2Fdownload%2F%40typescript-eslint%2Feslint-plugin-3.6.1.tgz"],
- ["@typescript-eslint/parser", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fparser%2Fdownload%2F%40typescript-eslint%2Fparser-3.6.1.tgz"],
+ ["@typescript-eslint/eslint-plugin", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Feslint-plugin%2Fdownload%2F%40typescript-eslint%2Feslint-plugin-3.9.1.tgz"],
+ ["@typescript-eslint/parser", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fparser%2Fdownload%2F%40typescript-eslint%2Fparser-3.9.1.tgz"],
["@yarnpkg/pnpify", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40yarnpkg%2Fpnpify%2Fdownload%2F%40yarnpkg%2Fpnpify-2.1.0.tgz"],
- ["axios", "npm:0.19.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.19.2.tgz"],
+ ["axios", "npm:0.20.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.20.0.tgz"],
["babel-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:8.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-loader%2Fdownload%2Fbabel-loader-8.1.0.tgz"],
["babel-plugin-transform-builtin-extend", "npm:1.1.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-plugin-transform-builtin-extend%2Fdownload%2Fbabel-plugin-transform-builtin-extend-1.1.2.tgz"],
- ["bootstrap", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbootstrap%2Fdownload%2Fbootstrap-4.5.0.tgz"],
+ ["bootstrap", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.5.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbootstrap%2Fdownload%2Fbootstrap-4.5.2.tgz"],
["bootstrap-icons", "npm:1.0.0-alpha5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbootstrap-icons%2Fdownload%2Fbootstrap-icons-1.0.0-alpha5.tgz"],
["classnames", "npm:2.2.6::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fclassnames%2Fdownload%2Fclassnames-2.2.6.tgz"],
["clean-webpack-plugin", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fclean-webpack-plugin%2Fdownload%2Fclean-webpack-plugin-3.0.0.tgz"],
@@ -401,43 +401,43 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["copy-webpack-plugin", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:6.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcopy-webpack-plugin%2Fdownload%2Fcopy-webpack-plugin-6.0.3.tgz"],
["core-js", "npm:3.6.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js%2Fdownload%2Fcore-js-3.6.5.tgz"],
["crypto-js", "npm:4.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcrypto-js%2Fdownload%2Fcrypto-js-4.0.0.tgz"],
- ["css-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-loader%2Fdownload%2Fcss-loader-3.6.0.tgz"],
- ["eslint", "npm:7.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.5.0.tgz"],
+ ["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-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.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-react%2Fdownload%2Feslint-plugin-react-7.20.3.tgz"],
- ["eslint-plugin-react-hooks", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.0.8::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-react-hooks%2Fdownload%2Feslint-plugin-react-hooks-4.0.8.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"],
["file-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:6.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffile-loader%2Fdownload%2Ffile-loader-6.0.0.tgz"],
- ["html-webpack-plugin", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-webpack-plugin%2Fdownload%2Fhtml-webpack-plugin-3.2.0.tgz"],
+ ["html-webpack-plugin", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-webpack-plugin%2Fdownload%2Fhtml-webpack-plugin-4.3.0.tgz"],
["http-server", "npm:0.12.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-server%2Fdownload%2Fhttp-server-0.12.3.tgz"],
- ["i18next", "npm:19.6.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next%2Fdownload%2Fi18next-19.6.2.tgz"],
- ["i18next-browser-languagedetector", "npm:5.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next-browser-languagedetector%2Fdownload%2Fi18next-browser-languagedetector-5.0.0.tgz"],
- ["localforage", "npm:1.7.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocalforage%2Fdownload%2Flocalforage-1.7.4.tgz"],
- ["lodash", "npm:4.17.19::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.19.tgz"],
+ ["i18next", "npm:19.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next%2Fdownload%2Fi18next-19.7.0.tgz"],
+ ["i18next-browser-languagedetector", "npm:6.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next-browser-languagedetector%2Fdownload%2Fi18next-browser-languagedetector-6.0.1.tgz"],
+ ["localforage", "npm:1.9.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocalforage%2Fdownload%2Flocalforage-1.9.0.tgz"],
+ ["lodash", "npm:4.17.20::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.20.tgz"],
["mini-css-extract-plugin", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:0.10.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fmini-css-extract-plugin%2Fdownload%2Fmini-css-extract-plugin-0.10.0.tgz"],
["pepjs", "npm:0.5.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpepjs%2Fdownload%2Fpepjs-0.5.2.tgz"],
["pnp-webpack-plugin", "npm:1.6.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpnp-webpack-plugin%2Fdownload%2Fpnp-webpack-plugin-1.6.4.tgz"],
["postcss-loader", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-loader%2Fdownload%2Fpostcss-loader-3.0.0.tgz"],
["postcss-preset-env", "npm:6.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-preset-env%2Fdownload%2Fpostcss-preset-env-6.7.0.tgz"],
- ["prettier", "npm:2.0.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-2.0.5.tgz"],
+ ["prettier", "npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-2.1.0.tgz"],
["react", "npm:16.13.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact%2Fdownload%2Freact-16.13.1.tgz"],
["react-dom", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:16.13.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-dom%2Fdownload%2Freact-dom-16.13.1.tgz"],
["react-hot-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.12.21::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-hot-loader%2Fdownload%2Freact-hot-loader-4.12.21.tgz"],
- ["react-i18next", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:11.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-i18next%2Fdownload%2Freact-i18next-11.7.0.tgz"],
+ ["react-i18next", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:11.7.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-i18next%2Fdownload%2Freact-i18next-11.7.1.tgz"],
["react-inlinesvg", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-inlinesvg%2Fdownload%2Freact-inlinesvg-2.0.0.tgz"],
["react-responsive", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:8.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-responsive%2Fdownload%2Freact-responsive-8.1.0.tgz"],
["react-router", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:5.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-router%2Fdownload%2Freact-router-5.2.0.tgz"],
["react-router-dom", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:5.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-router-dom%2Fdownload%2Freact-router-dom-5.2.0.tgz"],
["reactstrap", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:8.5.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freactstrap%2Fdownload%2Freactstrap-8.5.1.tgz"],
- ["regenerator-runtime", "npm:0.13.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.13.5.tgz"],
- ["rxjs", "npm:6.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Frxjs%2Fdownload%2Frxjs-6.6.0.tgz"],
+ ["regenerator-runtime", "npm:0.13.7::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.13.7.tgz"],
+ ["rxjs", "npm:6.6.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Frxjs%2Fdownload%2Frxjs-6.6.2.tgz"],
["sass", "npm:1.26.10::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsass%2Fdownload%2Fsass-1.26.10.tgz"],
- ["sass-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:9.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsass-loader%2Fdownload%2Fsass-loader-9.0.2.tgz"],
+ ["sass-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:9.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsass-loader%2Fdownload%2Fsass-loader-9.0.3.tgz"],
["style-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:1.2.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fstyle-loader%2Fdownload%2Fstyle-loader-1.2.1.tgz"],
- ["ts-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:8.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fts-loader%2Fdownload%2Fts-loader-8.0.1.tgz"],
- ["typescript", "patch:typescript@npm%3A3.9.7%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-3.9.7.tgz#builtin<compat/typescript>::version=3.9.7&hash=5b02a2"],
+ ["ts-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:8.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fts-loader%2Fdownload%2Fts-loader-8.0.3.tgz"],
+ ["typescript", "patch:typescript@npm%3A4.0.2%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-4.0.2.tgz#builtin<compat/typescript>::version=4.0.2&hash=5b02a2"],
["url-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Furl-loader%2Fdownload%2Furl-loader-4.1.0.tgz"],
- ["webpack", "npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz"],
+ ["webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"],
["webpack-chain", "npm:6.5.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-chain%2Fdownload%2Fwebpack-chain-6.5.1.tgz"],
["webpack-cli", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.3.12::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-cli%2Fdownload%2Fwebpack-cli-3.3.12.tgz"],
["webpack-dev-server", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-dev-server%2Fdownload%2Fwebpack-dev-server-3.11.0.tgz"],
@@ -481,6 +481,16 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["semver", "npm:5.7.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz"]
],
"linkType": "HARD",
+ }],
+ ["npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcompat-data%2Fdownload%2F%40babel%2Fcompat-data-7.11.0.tgz", {
+ "packageLocation": "./.yarn/cache/@babel-compat-data-npm-7.11.0-bd56151800-6c3b394654.zip/node_modules/@babel/compat-data/",
+ "packageDependencies": [
+ ["@babel/compat-data", "npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcompat-data%2Fdownload%2F%40babel%2Fcompat-data-7.11.0.tgz"],
+ ["browserslist", "npm:4.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbrowserslist%2Fdownload%2Fbrowserslist-4.13.0.tgz"],
+ ["invariant", "npm:2.2.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Finvariant%2Fdownload%2Finvariant-2.2.4.tgz"],
+ ["semver", "npm:5.7.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz"]
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/core", [
@@ -506,6 +516,29 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["source-map", "npm:0.5.7::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.5.7.tgz"]
],
"linkType": "HARD",
+ }],
+ ["npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz", {
+ "packageLocation": "./.yarn/cache/@babel-core-npm-7.11.4-8349e2f4f6-21b40a4242.zip/node_modules/@babel/core/",
+ "packageDependencies": [
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/code-frame", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcode-frame%2Fdownload%2F%40babel%2Fcode-frame-7.10.4.tgz"],
+ ["@babel/generator", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fgenerator%2Fdownload%2F%40babel%2Fgenerator-7.11.4.tgz"],
+ ["@babel/helper-module-transforms", "npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-transforms%2Fdownload%2F%40babel%2Fhelper-module-transforms-7.11.0.tgz"],
+ ["@babel/helpers", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelpers%2Fdownload%2F%40babel%2Fhelpers-7.10.4.tgz"],
+ ["@babel/parser", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fparser%2Fdownload%2F%40babel%2Fparser-7.11.4.tgz"],
+ ["@babel/template", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftemplate%2Fdownload%2F%40babel%2Ftemplate-7.10.4.tgz"],
+ ["@babel/traverse", "npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftraverse%2Fdownload%2F%40babel%2Ftraverse-7.11.0.tgz"],
+ ["@babel/types", "npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.11.0.tgz"],
+ ["convert-source-map", "npm:1.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fconvert-source-map%2Fdownload%2Fconvert-source-map-1.7.0.tgz"],
+ ["debug", "virtual:1e7fd7cbf468e9bdfe63ec86a342d405dc91ac84c8bb9894805983f8c23226bd5a88ff6423eed3317b91c46b7e9258b9c2030fa7275a62d19703cdbb018c2efc#npm:4.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz"],
+ ["gensync", "npm:1.0.0-beta.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fgensync%2Fdownload%2Fgensync-1.0.0-beta.1.tgz"],
+ ["json5", "npm:2.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson5%2Fdownload%2Fjson5-2.1.3.tgz"],
+ ["lodash", "npm:4.17.19::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.19.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"],
+ ["source-map", "npm:0.5.7::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.5.7.tgz"]
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/generator", [
@@ -518,6 +551,16 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["source-map", "npm:0.5.7::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.5.7.tgz"]
],
"linkType": "HARD",
+ }],
+ ["npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fgenerator%2Fdownload%2F%40babel%2Fgenerator-7.11.4.tgz", {
+ "packageLocation": "./.yarn/cache/@babel-generator-npm-7.11.4-c4496d80e8-1244facf6e.zip/node_modules/@babel/generator/",
+ "packageDependencies": [
+ ["@babel/generator", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fgenerator%2Fdownload%2F%40babel%2Fgenerator-7.11.4.tgz"],
+ ["@babel/types", "npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.11.0.tgz"],
+ ["jsesc", "npm:2.5.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fjsesc%2Fdownload%2Fjsesc-2.5.2.tgz"],
+ ["source-map", "npm:0.5.7::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.5.7.tgz"]
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/helper-annotate-as-pure", [
@@ -565,10 +608,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/helper-compilation-targets", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-compilation-targets%2Fdownload%2F%40babel%2Fhelper-compilation-targets-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-helper-compilation-targets-virtual-c37bf5d3d9/0/cache/@babel-helper-compilation-targets-npm-7.10.4-a08cf328fe-7603388e45.zip/node_modules/@babel/helper-compilation-targets/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-compilation-targets%2Fdownload%2F%40babel%2Fhelper-compilation-targets-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-helper-compilation-targets-virtual-afc3e08af4/0/cache/@babel-helper-compilation-targets-npm-7.10.4-a08cf328fe-7603388e45.zip/node_modules/@babel/helper-compilation-targets/",
"packageDependencies": [
- ["@babel/helper-compilation-targets", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-compilation-targets%2Fdownload%2F%40babel%2Fhelper-compilation-targets-7.10.4.tgz"],
+ ["@babel/helper-compilation-targets", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-compilation-targets%2Fdownload%2F%40babel%2Fhelper-compilation-targets-7.10.4.tgz"],
["@babel/compat-data", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcompat-data%2Fdownload%2F%40babel%2Fcompat-data-7.10.5.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["browserslist", "npm:4.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbrowserslist%2Fdownload%2Fbrowserslist-4.13.0.tgz"],
@@ -580,6 +623,22 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-compilation-targets%2Fdownload%2F%40babel%2Fhelper-compilation-targets-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-helper-compilation-targets-virtual-73dfa32bd6/0/cache/@babel-helper-compilation-targets-npm-7.10.4-a08cf328fe-7603388e45.zip/node_modules/@babel/helper-compilation-targets/",
+ "packageDependencies": [
+ ["@babel/helper-compilation-targets", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-compilation-targets%2Fdownload%2F%40babel%2Fhelper-compilation-targets-7.10.4.tgz"],
+ ["@babel/compat-data", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcompat-data%2Fdownload%2F%40babel%2Fcompat-data-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["browserslist", "npm:4.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbrowserslist%2Fdownload%2Fbrowserslist-4.13.0.tgz"],
+ ["invariant", "npm:2.2.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Finvariant%2Fdownload%2Finvariant-2.2.4.tgz"],
+ ["levenary", "npm:1.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flevenary%2Fdownload%2Flevenary-1.1.1.tgz"],
+ ["semver", "npm:5.7.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/helper-create-class-features-plugin", [
@@ -587,6 +646,23 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./.yarn/$$virtual/@babel-helper-create-class-features-plugin-virtual-6ac1469ea3/0/cache/@babel-helper-create-class-features-plugin-npm-7.10.5-80d2a751d6-ba8fb0f7b7.zip/node_modules/@babel/helper-create-class-features-plugin/",
"packageDependencies": [
["@babel/helper-create-class-features-plugin", "virtual:75c4dd0d2cd4b70bccb9932d6191569166cd0d5b906f73a0fa2e9f1a8aa2083703807d3c72e28f347cb193c2d3d3c614c438b60e7caa972fcd47c4edfe631ffd#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-class-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-class-features-plugin-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-function-name", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-function-name%2Fdownload%2F%40babel%2Fhelper-function-name-7.10.4.tgz"],
+ ["@babel/helper-member-expression-to-functions", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-member-expression-to-functions%2Fdownload%2F%40babel%2Fhelper-member-expression-to-functions-7.10.5.tgz"],
+ ["@babel/helper-optimise-call-expression", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-optimise-call-expression%2Fdownload%2F%40babel%2Fhelper-optimise-call-expression-7.10.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
+ ["@babel/helper-replace-supers", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-replace-supers%2Fdownload%2F%40babel%2Fhelper-replace-supers-7.10.4.tgz"],
+ ["@babel/helper-split-export-declaration", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-split-export-declaration%2Fdownload%2F%40babel%2Fhelper-split-export-declaration-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }],
+ ["virtual:d362e50edbaec44487ab4254ffabad17da5838ecc33597cc897b25295e12c3d0c63c66ea7afde463e1c2ec9fbf7602f962cefe087c61460304394941f05e2079#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-class-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-class-features-plugin-7.10.5.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-helper-create-class-features-plugin-virtual-422bc41b33/0/cache/@babel-helper-create-class-features-plugin-npm-7.10.5-80d2a751d6-ba8fb0f7b7.zip/node_modules/@babel/helper-create-class-features-plugin/",
+ "packageDependencies": [
+ ["@babel/helper-create-class-features-plugin", "virtual:d362e50edbaec44487ab4254ffabad17da5838ecc33597cc897b25295e12c3d0c63c66ea7afde463e1c2ec9fbf7602f962cefe087c61460304394941f05e2079#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-class-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-class-features-plugin-7.10.5.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-function-name", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-function-name%2Fdownload%2F%40babel%2Fhelper-function-name-7.10.4.tgz"],
["@babel/helper-member-expression-to-functions", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-member-expression-to-functions%2Fdownload%2F%40babel%2Fhelper-member-expression-to-functions-7.10.5.tgz"],
@@ -602,10 +678,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/helper-create-regexp-features-plugin", [
- ["virtual:4e95dff1e4d799ff1ad5b1d72fb9e856f303a7db3c862cc93ca2390c538394d4a4a141e0cac4effa2a8dba9bf2e598221f9095418d8d91d03b81ae16281a991b#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-regexp-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-regexp-features-plugin-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-helper-create-regexp-features-plugin-virtual-4fd0a4d97b/0/cache/@babel-helper-create-regexp-features-plugin-npm-7.10.4-286ead1d54-6d1728b614.zip/node_modules/@babel/helper-create-regexp-features-plugin/",
+ ["virtual:603d46702a42ce5c1028458dccd33e2fb1f5c8827f04e28a6705e7321c377b2ceab089d1924f8dc9a3517025ec0466db221bd611c0c591fb724085dc966cc3fc#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-regexp-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-regexp-features-plugin-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-helper-create-regexp-features-plugin-virtual-76b8fda6fe/0/cache/@babel-helper-create-regexp-features-plugin-npm-7.10.4-286ead1d54-6d1728b614.zip/node_modules/@babel/helper-create-regexp-features-plugin/",
"packageDependencies": [
- ["@babel/helper-create-regexp-features-plugin", "virtual:4e95dff1e4d799ff1ad5b1d72fb9e856f303a7db3c862cc93ca2390c538394d4a4a141e0cac4effa2a8dba9bf2e598221f9095418d8d91d03b81ae16281a991b#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-regexp-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-regexp-features-plugin-7.10.4.tgz"],
+ ["@babel/helper-create-regexp-features-plugin", "virtual:603d46702a42ce5c1028458dccd33e2fb1f5c8827f04e28a6705e7321c377b2ceab089d1924f8dc9a3517025ec0466db221bd611c0c591fb724085dc966cc3fc#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-regexp-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-regexp-features-plugin-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-annotate-as-pure", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-annotate-as-pure%2Fdownload%2F%40babel%2Fhelper-annotate-as-pure-7.10.4.tgz"],
["@babel/helper-regex", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-regex%2Fdownload%2F%40babel%2Fhelper-regex-7.10.5.tgz"],
@@ -615,6 +691,20 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:cb2dd087c703ec7307b541f992f3886d88eb72680bfa1ed88da28ff8b65d87d95e29d9e038cf20b422f8c09e4062de4c8890d7150f32e96e4d9866ffa2fdb838#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-regexp-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-regexp-features-plugin-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-helper-create-regexp-features-plugin-virtual-3b8e7c5ab7/0/cache/@babel-helper-create-regexp-features-plugin-npm-7.10.4-286ead1d54-6d1728b614.zip/node_modules/@babel/helper-create-regexp-features-plugin/",
+ "packageDependencies": [
+ ["@babel/helper-create-regexp-features-plugin", "virtual:cb2dd087c703ec7307b541f992f3886d88eb72680bfa1ed88da28ff8b65d87d95e29d9e038cf20b422f8c09e4062de4c8890d7150f32e96e4d9866ffa2fdb838#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-regexp-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-regexp-features-plugin-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-annotate-as-pure", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-annotate-as-pure%2Fdownload%2F%40babel%2Fhelper-annotate-as-pure-7.10.4.tgz"],
+ ["@babel/helper-regex", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-regex%2Fdownload%2F%40babel%2Fhelper-regex-7.10.5.tgz"],
+ ["regexpu-core", "npm:4.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fregexpu-core%2Fdownload%2Fregexpu-core-4.7.0.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/helper-define-map", [
@@ -706,6 +796,20 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["lodash", "npm:4.17.19::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.19.tgz"]
],
"linkType": "HARD",
+ }],
+ ["npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-transforms%2Fdownload%2F%40babel%2Fhelper-module-transforms-7.11.0.tgz", {
+ "packageLocation": "./.yarn/cache/@babel-helper-module-transforms-npm-7.11.0-eadb13f660-8b74d0a729.zip/node_modules/@babel/helper-module-transforms/",
+ "packageDependencies": [
+ ["@babel/helper-module-transforms", "npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-transforms%2Fdownload%2F%40babel%2Fhelper-module-transforms-7.11.0.tgz"],
+ ["@babel/helper-module-imports", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-imports%2Fdownload%2F%40babel%2Fhelper-module-imports-7.10.4.tgz"],
+ ["@babel/helper-replace-supers", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-replace-supers%2Fdownload%2F%40babel%2Fhelper-replace-supers-7.10.4.tgz"],
+ ["@babel/helper-simple-access", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-simple-access%2Fdownload%2F%40babel%2Fhelper-simple-access-7.10.4.tgz"],
+ ["@babel/helper-split-export-declaration", "npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-split-export-declaration%2Fdownload%2F%40babel%2Fhelper-split-export-declaration-7.11.0.tgz"],
+ ["@babel/template", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftemplate%2Fdownload%2F%40babel%2Ftemplate-7.10.4.tgz"],
+ ["@babel/types", "npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.11.0.tgz"],
+ ["lodash", "npm:4.17.19::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.19.tgz"]
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/helper-optimise-call-expression", [
@@ -775,6 +879,16 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD",
}]
]],
+ ["@babel/helper-skip-transparent-expression-wrappers", [
+ ["npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-skip-transparent-expression-wrappers%2Fdownload%2F%40babel%2Fhelper-skip-transparent-expression-wrappers-7.11.0.tgz", {
+ "packageLocation": "./.yarn/cache/@babel-helper-skip-transparent-expression-wrappers-npm-7.11.0-2f273a8378-c5995c834f.zip/node_modules/@babel/helper-skip-transparent-expression-wrappers/",
+ "packageDependencies": [
+ ["@babel/helper-skip-transparent-expression-wrappers", "npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-skip-transparent-expression-wrappers%2Fdownload%2F%40babel%2Fhelper-skip-transparent-expression-wrappers-7.11.0.tgz"],
+ ["@babel/types", "npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.11.0.tgz"]
+ ],
+ "linkType": "HARD",
+ }]
+ ]],
["@babel/helper-split-export-declaration", [
["npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-split-export-declaration%2Fdownload%2F%40babel%2Fhelper-split-export-declaration-7.10.4.tgz", {
"packageLocation": "./.yarn/cache/@babel-helper-split-export-declaration-npm-7.10.4-6e04a73c77-d8536faa40.zip/node_modules/@babel/helper-split-export-declaration/",
@@ -783,6 +897,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@babel/types", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.10.5.tgz"]
],
"linkType": "HARD",
+ }],
+ ["npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-split-export-declaration%2Fdownload%2F%40babel%2Fhelper-split-export-declaration-7.11.0.tgz", {
+ "packageLocation": "./.yarn/cache/@babel-helper-split-export-declaration-npm-7.11.0-dfda667eda-ddfc44d0cf.zip/node_modules/@babel/helper-split-export-declaration/",
+ "packageDependencies": [
+ ["@babel/helper-split-export-declaration", "npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-split-export-declaration%2Fdownload%2F%40babel%2Fhelper-split-export-declaration-7.11.0.tgz"],
+ ["@babel/types", "npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.11.0.tgz"]
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/helper-validator-identifier", [
@@ -838,17 +960,38 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@babel/parser", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fparser%2Fdownload%2F%40babel%2Fparser-7.10.5.tgz"]
],
"linkType": "HARD",
+ }],
+ ["npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fparser%2Fdownload%2F%40babel%2Fparser-7.11.4.tgz", {
+ "packageLocation": "./.yarn/cache/@babel-parser-npm-7.11.4-7437faee1f-06337dd30f.zip/node_modules/@babel/parser/",
+ "packageDependencies": [
+ ["@babel/parser", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fparser%2Fdownload%2F%40babel%2Fparser-7.11.4.tgz"]
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-proposal-async-generator-functions", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-async-generator-functions%2Fdownload%2F%40babel%2Fplugin-proposal-async-generator-functions-7.10.5.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-async-generator-functions-virtual-81fcd64b55/0/cache/@babel-plugin-proposal-async-generator-functions-npm-7.10.5-a4d63fbc72-d43c72c330.zip/node_modules/@babel/plugin-proposal-async-generator-functions/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-async-generator-functions%2Fdownload%2F%40babel%2Fplugin-proposal-async-generator-functions-7.10.5.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-async-generator-functions-virtual-f04ff0ccce/0/cache/@babel-plugin-proposal-async-generator-functions-npm-7.10.5-a4d63fbc72-d43c72c330.zip/node_modules/@babel/plugin-proposal-async-generator-functions/",
"packageDependencies": [
- ["@babel/plugin-proposal-async-generator-functions", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-async-generator-functions%2Fdownload%2F%40babel%2Fplugin-proposal-async-generator-functions-7.10.5.tgz"],
+ ["@babel/plugin-proposal-async-generator-functions", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-async-generator-functions%2Fdownload%2F%40babel%2Fplugin-proposal-async-generator-functions-7.10.5.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
["@babel/helper-remap-async-to-generator", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-remap-async-to-generator%2Fdownload%2F%40babel%2Fhelper-remap-async-to-generator-7.10.4.tgz"],
- ["@babel/plugin-syntax-async-generators", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.8.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-async-generators%2Fdownload%2F%40babel%2Fplugin-syntax-async-generators-7.8.4.tgz"]
+ ["@babel/plugin-syntax-async-generators", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-async-generators%2Fdownload%2F%40babel%2Fplugin-syntax-async-generators-7.8.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-async-generator-functions%2Fdownload%2F%40babel%2Fplugin-proposal-async-generator-functions-7.10.5.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-async-generator-functions-virtual-f1742c570b/0/cache/@babel-plugin-proposal-async-generator-functions-npm-7.10.5-a4d63fbc72-d43c72c330.zip/node_modules/@babel/plugin-proposal-async-generator-functions/",
+ "packageDependencies": [
+ ["@babel/plugin-proposal-async-generator-functions", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-async-generator-functions%2Fdownload%2F%40babel%2Fplugin-proposal-async-generator-functions-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
+ ["@babel/helper-remap-async-to-generator", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-remap-async-to-generator%2Fdownload%2F%40babel%2Fhelper-remap-async-to-generator-7.10.4.tgz"],
+ ["@babel/plugin-syntax-async-generators", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.8.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-async-generators%2Fdownload%2F%40babel%2Fplugin-syntax-async-generators-7.8.4.tgz"]
],
"packagePeers": [
"@babel/core"
@@ -857,11 +1000,24 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/plugin-proposal-class-properties", [
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-class-properties%2Fdownload%2F%40babel%2Fplugin-proposal-class-properties-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-class-properties-virtual-d362e50edb/0/cache/@babel-plugin-proposal-class-properties-npm-7.10.4-169fe0dcbf-32cf34c077.zip/node_modules/@babel/plugin-proposal-class-properties/",
+ "packageDependencies": [
+ ["@babel/plugin-proposal-class-properties", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-class-properties%2Fdownload%2F%40babel%2Fplugin-proposal-class-properties-7.10.4.tgz"],
+ ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/helper-create-class-features-plugin", "virtual:d362e50edbaec44487ab4254ffabad17da5838ecc33597cc897b25295e12c3d0c63c66ea7afde463e1c2ec9fbf7602f962cefe087c61460304394941f05e2079#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-class-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-class-features-plugin-7.10.5.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }],
["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-class-properties%2Fdownload%2F%40babel%2Fplugin-proposal-class-properties-7.10.4.tgz", {
"packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-class-properties-virtual-75c4dd0d2c/0/cache/@babel-plugin-proposal-class-properties-npm-7.10.4-169fe0dcbf-32cf34c077.zip/node_modules/@babel/plugin-proposal-class-properties/",
"packageDependencies": [
["@babel/plugin-proposal-class-properties", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-class-properties%2Fdownload%2F%40babel%2Fplugin-proposal-class-properties-7.10.4.tgz"],
- ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
["@babel/helper-create-class-features-plugin", "virtual:75c4dd0d2cd4b70bccb9932d6191569166cd0d5b906f73a0fa2e9f1a8aa2083703807d3c72e28f347cb193c2d3d3c614c438b60e7caa972fcd47c4edfe631ffd#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-class-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-class-features-plugin-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -876,7 +1032,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-decorators-virtual-33a8bdc567/0/cache/@babel-plugin-proposal-decorators-npm-7.10.5-6a43bc4dde-32be038dd2.zip/node_modules/@babel/plugin-proposal-decorators/",
"packageDependencies": [
["@babel/plugin-proposal-decorators", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-decorators%2Fdownload%2F%40babel%2Fplugin-proposal-decorators-7.10.5.tgz"],
- ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
["@babel/helper-create-class-features-plugin", "virtual:75c4dd0d2cd4b70bccb9932d6191569166cd0d5b906f73a0fa2e9f1a8aa2083703807d3c72e28f347cb193c2d3d3c614c438b60e7caa972fcd47c4edfe631ffd#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-class-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-class-features-plugin-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
["@babel/plugin-syntax-decorators", "virtual:33a8bdc56727ef63c1552f223e064c75282a0f7f50a591d24d030b7eb1ab956b8d64ce90fc9a35dcf12b5d11b283a6ebbd81abfec8ddcba9a194d6356268162b#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-decorators%2Fdownload%2F%40babel%2Fplugin-syntax-decorators-7.10.4.tgz"]
@@ -888,12 +1044,25 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/plugin-proposal-dynamic-import", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-dynamic-import%2Fdownload%2F%40babel%2Fplugin-proposal-dynamic-import-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-dynamic-import-virtual-68b0ae73c9/0/cache/@babel-plugin-proposal-dynamic-import-npm-7.10.4-6fba0608fa-0ded8305a7.zip/node_modules/@babel/plugin-proposal-dynamic-import/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-dynamic-import%2Fdownload%2F%40babel%2Fplugin-proposal-dynamic-import-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-dynamic-import-virtual-339ffeffd0/0/cache/@babel-plugin-proposal-dynamic-import-npm-7.10.4-6fba0608fa-0ded8305a7.zip/node_modules/@babel/plugin-proposal-dynamic-import/",
"packageDependencies": [
- ["@babel/plugin-proposal-dynamic-import", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-dynamic-import%2Fdownload%2F%40babel%2Fplugin-proposal-dynamic-import-7.10.4.tgz"],
+ ["@babel/plugin-proposal-dynamic-import", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-dynamic-import%2Fdownload%2F%40babel%2Fplugin-proposal-dynamic-import-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
+ ["@babel/plugin-syntax-dynamic-import", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-dynamic-import%2Fdownload%2F%40babel%2Fplugin-syntax-dynamic-import-7.8.3.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-dynamic-import%2Fdownload%2F%40babel%2Fplugin-proposal-dynamic-import-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-dynamic-import-virtual-19fc4b57e3/0/cache/@babel-plugin-proposal-dynamic-import-npm-7.10.4-6fba0608fa-0ded8305a7.zip/node_modules/@babel/plugin-proposal-dynamic-import/",
+ "packageDependencies": [
+ ["@babel/plugin-proposal-dynamic-import", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-dynamic-import%2Fdownload%2F%40babel%2Fplugin-proposal-dynamic-import-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
["@babel/plugin-syntax-dynamic-import", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-dynamic-import%2Fdownload%2F%40babel%2Fplugin-syntax-dynamic-import-7.8.3.tgz"]
],
"packagePeers": [
@@ -902,14 +1071,57 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD",
}]
]],
+ ["@babel/plugin-proposal-export-namespace-from", [
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-export-namespace-from%2Fdownload%2F%40babel%2Fplugin-proposal-export-namespace-from-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-export-namespace-from-virtual-ed807963f0/0/cache/@babel-plugin-proposal-export-namespace-from-npm-7.10.4-d3320b3e58-b17727e66f.zip/node_modules/@babel/plugin-proposal-export-namespace-from/",
+ "packageDependencies": [
+ ["@babel/plugin-proposal-export-namespace-from", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-export-namespace-from%2Fdownload%2F%40babel%2Fplugin-proposal-export-namespace-from-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
+ ["@babel/plugin-syntax-export-namespace-from", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-export-namespace-from%2Fdownload%2F%40babel%2Fplugin-syntax-export-namespace-from-7.8.3.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }]
+ ]],
["@babel/plugin-proposal-json-strings", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-json-strings%2Fdownload%2F%40babel%2Fplugin-proposal-json-strings-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-json-strings-virtual-13e67c567c/0/cache/@babel-plugin-proposal-json-strings-npm-7.10.4-57f37b8a72-3403971661.zip/node_modules/@babel/plugin-proposal-json-strings/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-json-strings%2Fdownload%2F%40babel%2Fplugin-proposal-json-strings-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-json-strings-virtual-58c48a2ae6/0/cache/@babel-plugin-proposal-json-strings-npm-7.10.4-57f37b8a72-3403971661.zip/node_modules/@babel/plugin-proposal-json-strings/",
"packageDependencies": [
- ["@babel/plugin-proposal-json-strings", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-json-strings%2Fdownload%2F%40babel%2Fplugin-proposal-json-strings-7.10.4.tgz"],
+ ["@babel/plugin-proposal-json-strings", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-json-strings%2Fdownload%2F%40babel%2Fplugin-proposal-json-strings-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
- ["@babel/plugin-syntax-json-strings", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-json-strings%2Fdownload%2F%40babel%2Fplugin-syntax-json-strings-7.8.3.tgz"]
+ ["@babel/plugin-syntax-json-strings", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-json-strings%2Fdownload%2F%40babel%2Fplugin-syntax-json-strings-7.8.3.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-json-strings%2Fdownload%2F%40babel%2Fplugin-proposal-json-strings-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-json-strings-virtual-948bd675c1/0/cache/@babel-plugin-proposal-json-strings-npm-7.10.4-57f37b8a72-3403971661.zip/node_modules/@babel/plugin-proposal-json-strings/",
+ "packageDependencies": [
+ ["@babel/plugin-proposal-json-strings", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-json-strings%2Fdownload%2F%40babel%2Fplugin-proposal-json-strings-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
+ ["@babel/plugin-syntax-json-strings", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-json-strings%2Fdownload%2F%40babel%2Fplugin-syntax-json-strings-7.8.3.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }]
+ ]],
+ ["@babel/plugin-proposal-logical-assignment-operators", [
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-logical-assignment-operators%2Fdownload%2F%40babel%2Fplugin-proposal-logical-assignment-operators-7.11.0.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-logical-assignment-operators-virtual-26f18287ec/0/cache/@babel-plugin-proposal-logical-assignment-operators-npm-7.11.0-0a1dfeabf4-a87e80bcfd.zip/node_modules/@babel/plugin-proposal-logical-assignment-operators/",
+ "packageDependencies": [
+ ["@babel/plugin-proposal-logical-assignment-operators", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-logical-assignment-operators%2Fdownload%2F%40babel%2Fplugin-proposal-logical-assignment-operators-7.11.0.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
+ ["@babel/plugin-syntax-logical-assignment-operators", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-logical-assignment-operators%2Fdownload%2F%40babel%2Fplugin-syntax-logical-assignment-operators-7.10.4.tgz"]
],
"packagePeers": [
"@babel/core"
@@ -918,11 +1130,24 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/plugin-proposal-nullish-coalescing-operator", [
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator%2Fdownload%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-nullish-coalescing-operator-virtual-bffd3ff978/0/cache/@babel-plugin-proposal-nullish-coalescing-operator-npm-7.10.4-de1cff6588-5a20d8bcbf.zip/node_modules/@babel/plugin-proposal-nullish-coalescing-operator/",
+ "packageDependencies": [
+ ["@babel/plugin-proposal-nullish-coalescing-operator", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator%2Fdownload%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator-7.10.4.tgz"],
+ ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
+ ["@babel/plugin-syntax-nullish-coalescing-operator", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-nullish-coalescing-operator%2Fdownload%2F%40babel%2Fplugin-syntax-nullish-coalescing-operator-7.8.3.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }],
["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator%2Fdownload%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator-7.10.4.tgz", {
"packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-nullish-coalescing-operator-virtual-1aafd484e7/0/cache/@babel-plugin-proposal-nullish-coalescing-operator-npm-7.10.4-de1cff6588-5a20d8bcbf.zip/node_modules/@babel/plugin-proposal-nullish-coalescing-operator/",
"packageDependencies": [
["@babel/plugin-proposal-nullish-coalescing-operator", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator%2Fdownload%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator-7.10.4.tgz"],
- ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
["@babel/plugin-syntax-nullish-coalescing-operator", "virtual:1aafd484e7c5739d9135bb3b82d8e863096fd061b8289a1e58fdc6707690db2c22912ae5275c7ec0ea6fb457d9aeba6d3d0f5d2e62cbebde76831d72dbc6b575#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-nullish-coalescing-operator%2Fdownload%2F%40babel%2Fplugin-syntax-nullish-coalescing-operator-7.8.3.tgz"]
],
@@ -933,13 +1158,26 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/plugin-proposal-numeric-separator", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-numeric-separator%2Fdownload%2F%40babel%2Fplugin-proposal-numeric-separator-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-numeric-separator-virtual-645aed56bd/0/cache/@babel-plugin-proposal-numeric-separator-npm-7.10.4-4723c89d30-344eff491f.zip/node_modules/@babel/plugin-proposal-numeric-separator/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-numeric-separator%2Fdownload%2F%40babel%2Fplugin-proposal-numeric-separator-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-numeric-separator-virtual-204ece3450/0/cache/@babel-plugin-proposal-numeric-separator-npm-7.10.4-4723c89d30-344eff491f.zip/node_modules/@babel/plugin-proposal-numeric-separator/",
"packageDependencies": [
- ["@babel/plugin-proposal-numeric-separator", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-numeric-separator%2Fdownload%2F%40babel%2Fplugin-proposal-numeric-separator-7.10.4.tgz"],
+ ["@babel/plugin-proposal-numeric-separator", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-numeric-separator%2Fdownload%2F%40babel%2Fplugin-proposal-numeric-separator-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
- ["@babel/plugin-syntax-numeric-separator", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-numeric-separator%2Fdownload%2F%40babel%2Fplugin-syntax-numeric-separator-7.10.4.tgz"]
+ ["@babel/plugin-syntax-numeric-separator", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-numeric-separator%2Fdownload%2F%40babel%2Fplugin-syntax-numeric-separator-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-numeric-separator%2Fdownload%2F%40babel%2Fplugin-proposal-numeric-separator-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-numeric-separator-virtual-e580888e07/0/cache/@babel-plugin-proposal-numeric-separator-npm-7.10.4-4723c89d30-344eff491f.zip/node_modules/@babel/plugin-proposal-numeric-separator/",
+ "packageDependencies": [
+ ["@babel/plugin-proposal-numeric-separator", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-numeric-separator%2Fdownload%2F%40babel%2Fplugin-proposal-numeric-separator-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
+ ["@babel/plugin-syntax-numeric-separator", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-numeric-separator%2Fdownload%2F%40babel%2Fplugin-syntax-numeric-separator-7.10.4.tgz"]
],
"packagePeers": [
"@babel/core"
@@ -948,14 +1186,28 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/plugin-proposal-object-rest-spread", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-proposal-object-rest-spread-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-object-rest-spread-virtual-5f5b250aba/0/cache/@babel-plugin-proposal-object-rest-spread-npm-7.10.4-bbab266965-eb09aa3de7.zip/node_modules/@babel/plugin-proposal-object-rest-spread/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-proposal-object-rest-spread-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-object-rest-spread-virtual-08647c6489/0/cache/@babel-plugin-proposal-object-rest-spread-npm-7.10.4-bbab266965-eb09aa3de7.zip/node_modules/@babel/plugin-proposal-object-rest-spread/",
"packageDependencies": [
- ["@babel/plugin-proposal-object-rest-spread", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-proposal-object-rest-spread-7.10.4.tgz"],
+ ["@babel/plugin-proposal-object-rest-spread", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-proposal-object-rest-spread-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
- ["@babel/plugin-syntax-object-rest-spread", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-syntax-object-rest-spread-7.8.3.tgz"],
- ["@babel/plugin-transform-parameters", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-parameters%2Fdownload%2F%40babel%2Fplugin-transform-parameters-7.10.5.tgz"]
+ ["@babel/plugin-syntax-object-rest-spread", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-syntax-object-rest-spread-7.8.3.tgz"],
+ ["@babel/plugin-transform-parameters", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-parameters%2Fdownload%2F%40babel%2Fplugin-transform-parameters-7.10.5.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-proposal-object-rest-spread-7.11.0.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-object-rest-spread-virtual-a9f9ae35d9/0/cache/@babel-plugin-proposal-object-rest-spread-npm-7.11.0-d8f339293f-5071094245.zip/node_modules/@babel/plugin-proposal-object-rest-spread/",
+ "packageDependencies": [
+ ["@babel/plugin-proposal-object-rest-spread", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-proposal-object-rest-spread-7.11.0.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
+ ["@babel/plugin-syntax-object-rest-spread", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-syntax-object-rest-spread-7.8.3.tgz"],
+ ["@babel/plugin-transform-parameters", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-parameters%2Fdownload%2F%40babel%2Fplugin-transform-parameters-7.10.5.tgz"]
],
"packagePeers": [
"@babel/core"
@@ -964,13 +1216,26 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/plugin-proposal-optional-catch-binding", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-proposal-optional-catch-binding-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-optional-catch-binding-virtual-d7cacf9ebb/0/cache/@babel-plugin-proposal-optional-catch-binding-npm-7.10.4-7e0f318dfc-56a3a62131.zip/node_modules/@babel/plugin-proposal-optional-catch-binding/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-proposal-optional-catch-binding-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-optional-catch-binding-virtual-93919456f3/0/cache/@babel-plugin-proposal-optional-catch-binding-npm-7.10.4-7e0f318dfc-56a3a62131.zip/node_modules/@babel/plugin-proposal-optional-catch-binding/",
"packageDependencies": [
- ["@babel/plugin-proposal-optional-catch-binding", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-proposal-optional-catch-binding-7.10.4.tgz"],
+ ["@babel/plugin-proposal-optional-catch-binding", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-proposal-optional-catch-binding-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
- ["@babel/plugin-syntax-optional-catch-binding", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-syntax-optional-catch-binding-7.8.3.tgz"]
+ ["@babel/plugin-syntax-optional-catch-binding", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-syntax-optional-catch-binding-7.8.3.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-proposal-optional-catch-binding-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-optional-catch-binding-virtual-de164b7f28/0/cache/@babel-plugin-proposal-optional-catch-binding-npm-7.10.4-7e0f318dfc-56a3a62131.zip/node_modules/@babel/plugin-proposal-optional-catch-binding/",
+ "packageDependencies": [
+ ["@babel/plugin-proposal-optional-catch-binding", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-proposal-optional-catch-binding-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
+ ["@babel/plugin-syntax-optional-catch-binding", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-syntax-optional-catch-binding-7.8.3.tgz"]
],
"packagePeers": [
"@babel/core"
@@ -979,13 +1244,27 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/plugin-proposal-optional-chaining", [
- ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-chaining%2Fdownload%2F%40babel%2Fplugin-proposal-optional-chaining-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-optional-chaining-virtual-303da2bcf7/0/cache/@babel-plugin-proposal-optional-chaining-npm-7.10.4-24a040b446-b086076509.zip/node_modules/@babel/plugin-proposal-optional-chaining/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-chaining%2Fdownload%2F%40babel%2Fplugin-proposal-optional-chaining-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-optional-chaining-virtual-4ce665bb83/0/cache/@babel-plugin-proposal-optional-chaining-npm-7.10.4-24a040b446-b086076509.zip/node_modules/@babel/plugin-proposal-optional-chaining/",
"packageDependencies": [
- ["@babel/plugin-proposal-optional-chaining", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-chaining%2Fdownload%2F%40babel%2Fplugin-proposal-optional-chaining-7.10.4.tgz"],
+ ["@babel/plugin-proposal-optional-chaining", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-chaining%2Fdownload%2F%40babel%2Fplugin-proposal-optional-chaining-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
- ["@babel/plugin-syntax-optional-chaining", "virtual:303da2bcf7cb54ecbdab5aadd757aceee31fcf731c58ada79b826235fd05987c4fd49cd36aa85ed9812896b79a14b330d14b59a9bb31b7a4f8a671b30938e476#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-chaining%2Fdownload%2F%40babel%2Fplugin-syntax-optional-chaining-7.8.3.tgz"]
+ ["@babel/plugin-syntax-optional-chaining", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-chaining%2Fdownload%2F%40babel%2Fplugin-syntax-optional-chaining-7.8.3.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }],
+ ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-chaining%2Fdownload%2F%40babel%2Fplugin-proposal-optional-chaining-7.11.0.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-optional-chaining-virtual-532709048c/0/cache/@babel-plugin-proposal-optional-chaining-npm-7.11.0-dd279c6d34-fb59410944.zip/node_modules/@babel/plugin-proposal-optional-chaining/",
+ "packageDependencies": [
+ ["@babel/plugin-proposal-optional-chaining", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-chaining%2Fdownload%2F%40babel%2Fplugin-proposal-optional-chaining-7.11.0.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
+ ["@babel/helper-skip-transparent-expression-wrappers", "npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-skip-transparent-expression-wrappers%2Fdownload%2F%40babel%2Fhelper-skip-transparent-expression-wrappers-7.11.0.tgz"],
+ ["@babel/plugin-syntax-optional-chaining", "virtual:532709048cb003cd2417daa5fea56a95b3adea6f1c98f15bbeccd431c941ab5303512f56d976e8c33d619655e94e289d317ca2dbc731adc82d3687ee5a2dd94b#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-chaining%2Fdownload%2F%40babel%2Fplugin-syntax-optional-chaining-7.8.3.tgz"]
],
"packagePeers": [
"@babel/core"
@@ -994,11 +1273,24 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/plugin-proposal-private-methods", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-private-methods%2Fdownload%2F%40babel%2Fplugin-proposal-private-methods-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-private-methods-virtual-f2d9ecbda3/0/cache/@babel-plugin-proposal-private-methods-npm-7.10.4-5b2cb8662f-7a29e63aaf.zip/node_modules/@babel/plugin-proposal-private-methods/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-private-methods%2Fdownload%2F%40babel%2Fplugin-proposal-private-methods-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-private-methods-virtual-7faff30e72/0/cache/@babel-plugin-proposal-private-methods-npm-7.10.4-5b2cb8662f-7a29e63aaf.zip/node_modules/@babel/plugin-proposal-private-methods/",
"packageDependencies": [
- ["@babel/plugin-proposal-private-methods", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-private-methods%2Fdownload%2F%40babel%2Fplugin-proposal-private-methods-7.10.4.tgz"],
+ ["@babel/plugin-proposal-private-methods", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-private-methods%2Fdownload%2F%40babel%2Fplugin-proposal-private-methods-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/helper-create-class-features-plugin", "virtual:d362e50edbaec44487ab4254ffabad17da5838ecc33597cc897b25295e12c3d0c63c66ea7afde463e1c2ec9fbf7602f962cefe087c61460304394941f05e2079#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-class-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-class-features-plugin-7.10.5.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-private-methods%2Fdownload%2F%40babel%2Fplugin-proposal-private-methods-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-private-methods-virtual-cda1da197e/0/cache/@babel-plugin-proposal-private-methods-npm-7.10.4-5b2cb8662f-7a29e63aaf.zip/node_modules/@babel/plugin-proposal-private-methods/",
+ "packageDependencies": [
+ ["@babel/plugin-proposal-private-methods", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-private-methods%2Fdownload%2F%40babel%2Fplugin-proposal-private-methods-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
["@babel/helper-create-class-features-plugin", "virtual:75c4dd0d2cd4b70bccb9932d6191569166cd0d5b906f73a0fa2e9f1a8aa2083703807d3c72e28f347cb193c2d3d3c614c438b60e7caa972fcd47c4edfe631ffd#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-class-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-class-features-plugin-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1009,12 +1301,25 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/plugin-proposal-unicode-property-regex", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-unicode-property-regex%2Fdownload%2F%40babel%2Fplugin-proposal-unicode-property-regex-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-unicode-property-regex-virtual-4e95dff1e4/0/cache/@babel-plugin-proposal-unicode-property-regex-npm-7.10.4-eff001b998-41e271cf08.zip/node_modules/@babel/plugin-proposal-unicode-property-regex/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-unicode-property-regex%2Fdownload%2F%40babel%2Fplugin-proposal-unicode-property-regex-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-unicode-property-regex-virtual-603d46702a/0/cache/@babel-plugin-proposal-unicode-property-regex-npm-7.10.4-eff001b998-41e271cf08.zip/node_modules/@babel/plugin-proposal-unicode-property-regex/",
"packageDependencies": [
- ["@babel/plugin-proposal-unicode-property-regex", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-unicode-property-regex%2Fdownload%2F%40babel%2Fplugin-proposal-unicode-property-regex-7.10.4.tgz"],
+ ["@babel/plugin-proposal-unicode-property-regex", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-unicode-property-regex%2Fdownload%2F%40babel%2Fplugin-proposal-unicode-property-regex-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
- ["@babel/helper-create-regexp-features-plugin", "virtual:4e95dff1e4d799ff1ad5b1d72fb9e856f303a7db3c862cc93ca2390c538394d4a4a141e0cac4effa2a8dba9bf2e598221f9095418d8d91d03b81ae16281a991b#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-regexp-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-regexp-features-plugin-7.10.4.tgz"],
+ ["@babel/helper-create-regexp-features-plugin", "virtual:603d46702a42ce5c1028458dccd33e2fb1f5c8827f04e28a6705e7321c377b2ceab089d1924f8dc9a3517025ec0466db221bd611c0c591fb724085dc966cc3fc#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-regexp-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-regexp-features-plugin-7.10.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-unicode-property-regex%2Fdownload%2F%40babel%2Fplugin-proposal-unicode-property-regex-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-proposal-unicode-property-regex-virtual-cb2dd087c7/0/cache/@babel-plugin-proposal-unicode-property-regex-npm-7.10.4-eff001b998-41e271cf08.zip/node_modules/@babel/plugin-proposal-unicode-property-regex/",
+ "packageDependencies": [
+ ["@babel/plugin-proposal-unicode-property-regex", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-unicode-property-regex%2Fdownload%2F%40babel%2Fplugin-proposal-unicode-property-regex-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-create-regexp-features-plugin", "virtual:cb2dd087c703ec7307b541f992f3886d88eb72680bfa1ed88da28ff8b65d87d95e29d9e038cf20b422f8c09e4062de4c8890d7150f32e96e4d9866ffa2fdb838#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-regexp-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-regexp-features-plugin-7.10.4.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
"packagePeers": [
@@ -1024,10 +1329,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/plugin-syntax-async-generators", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.8.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-async-generators%2Fdownload%2F%40babel%2Fplugin-syntax-async-generators-7.8.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-async-generators-virtual-abc3a3aa4b/0/cache/@babel-plugin-syntax-async-generators-npm-7.8.4-149971faf5-39685944ff.zip/node_modules/@babel/plugin-syntax-async-generators/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-async-generators%2Fdownload%2F%40babel%2Fplugin-syntax-async-generators-7.8.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-async-generators-virtual-7a96e68354/0/cache/@babel-plugin-syntax-async-generators-npm-7.8.4-149971faf5-39685944ff.zip/node_modules/@babel/plugin-syntax-async-generators/",
"packageDependencies": [
- ["@babel/plugin-syntax-async-generators", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.8.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-async-generators%2Fdownload%2F%40babel%2Fplugin-syntax-async-generators-7.8.4.tgz"],
+ ["@babel/plugin-syntax-async-generators", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-async-generators%2Fdownload%2F%40babel%2Fplugin-syntax-async-generators-7.8.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1035,13 +1340,25 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.8.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-async-generators%2Fdownload%2F%40babel%2Fplugin-syntax-async-generators-7.8.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-async-generators-virtual-458e0e0070/0/cache/@babel-plugin-syntax-async-generators-npm-7.8.4-149971faf5-39685944ff.zip/node_modules/@babel/plugin-syntax-async-generators/",
+ "packageDependencies": [
+ ["@babel/plugin-syntax-async-generators", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.8.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-async-generators%2Fdownload%2F%40babel%2Fplugin-syntax-async-generators-7.8.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-syntax-class-properties", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-class-properties%2Fdownload%2F%40babel%2Fplugin-syntax-class-properties-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-class-properties-virtual-101798e3ca/0/cache/@babel-plugin-syntax-class-properties-npm-7.10.4-33690cde9b-8d0c1a3f5a.zip/node_modules/@babel/plugin-syntax-class-properties/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-class-properties%2Fdownload%2F%40babel%2Fplugin-syntax-class-properties-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-class-properties-virtual-985b507aa5/0/cache/@babel-plugin-syntax-class-properties-npm-7.10.4-33690cde9b-8d0c1a3f5a.zip/node_modules/@babel/plugin-syntax-class-properties/",
"packageDependencies": [
- ["@babel/plugin-syntax-class-properties", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-class-properties%2Fdownload%2F%40babel%2Fplugin-syntax-class-properties-7.10.4.tgz"],
+ ["@babel/plugin-syntax-class-properties", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-class-properties%2Fdownload%2F%40babel%2Fplugin-syntax-class-properties-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1049,6 +1366,18 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-class-properties%2Fdownload%2F%40babel%2Fplugin-syntax-class-properties-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-class-properties-virtual-76bfa608ed/0/cache/@babel-plugin-syntax-class-properties-npm-7.10.4-33690cde9b-8d0c1a3f5a.zip/node_modules/@babel/plugin-syntax-class-properties/",
+ "packageDependencies": [
+ ["@babel/plugin-syntax-class-properties", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-class-properties%2Fdownload%2F%40babel%2Fplugin-syntax-class-properties-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-syntax-decorators", [
@@ -1056,7 +1385,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-decorators-virtual-0c34241b9e/0/cache/@babel-plugin-syntax-decorators-npm-7.10.4-9eaba778eb-61a68e950b.zip/node_modules/@babel/plugin-syntax-decorators/",
"packageDependencies": [
["@babel/plugin-syntax-decorators", "virtual:33a8bdc56727ef63c1552f223e064c75282a0f7f50a591d24d030b7eb1ab956b8d64ce90fc9a35dcf12b5d11b283a6ebbd81abfec8ddcba9a194d6356268162b#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-decorators%2Fdownload%2F%40babel%2Fplugin-syntax-decorators-7.10.4.tgz"],
- ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
"packagePeers": [
@@ -1066,11 +1395,37 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/plugin-syntax-dynamic-import", [
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-dynamic-import%2Fdownload%2F%40babel%2Fplugin-syntax-dynamic-import-7.8.3.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-dynamic-import-virtual-43278fa8ba/0/cache/@babel-plugin-syntax-dynamic-import-npm-7.8.3-d93fc82802-134a6f37fe.zip/node_modules/@babel/plugin-syntax-dynamic-import/",
+ "packageDependencies": [
+ ["@babel/plugin-syntax-dynamic-import", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-dynamic-import%2Fdownload%2F%40babel%2Fplugin-syntax-dynamic-import-7.8.3.tgz"],
+ ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }],
["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-dynamic-import%2Fdownload%2F%40babel%2Fplugin-syntax-dynamic-import-7.8.3.tgz", {
"packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-dynamic-import-virtual-2e0c56d63e/0/cache/@babel-plugin-syntax-dynamic-import-npm-7.8.3-d93fc82802-134a6f37fe.zip/node_modules/@babel/plugin-syntax-dynamic-import/",
"packageDependencies": [
["@babel/plugin-syntax-dynamic-import", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-dynamic-import%2Fdownload%2F%40babel%2Fplugin-syntax-dynamic-import-7.8.3.tgz"],
- ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }]
+ ]],
+ ["@babel/plugin-syntax-export-namespace-from", [
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-export-namespace-from%2Fdownload%2F%40babel%2Fplugin-syntax-export-namespace-from-7.8.3.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-export-namespace-from-virtual-c380b34531/0/cache/@babel-plugin-syntax-export-namespace-from-npm-7.8.3-4b4610d529-832e007319.zip/node_modules/@babel/plugin-syntax-export-namespace-from/",
+ "packageDependencies": [
+ ["@babel/plugin-syntax-export-namespace-from", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-export-namespace-from%2Fdownload%2F%40babel%2Fplugin-syntax-export-namespace-from-7.8.3.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
"packagePeers": [
@@ -1080,10 +1435,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/plugin-syntax-json-strings", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-json-strings%2Fdownload%2F%40babel%2Fplugin-syntax-json-strings-7.8.3.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-json-strings-virtual-484bb25ad3/0/cache/@babel-plugin-syntax-json-strings-npm-7.8.3-ce7987f347-1a7dabf0a4.zip/node_modules/@babel/plugin-syntax-json-strings/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-json-strings%2Fdownload%2F%40babel%2Fplugin-syntax-json-strings-7.8.3.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-json-strings-virtual-a330e5310f/0/cache/@babel-plugin-syntax-json-strings-npm-7.8.3-ce7987f347-1a7dabf0a4.zip/node_modules/@babel/plugin-syntax-json-strings/",
"packageDependencies": [
- ["@babel/plugin-syntax-json-strings", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-json-strings%2Fdownload%2F%40babel%2Fplugin-syntax-json-strings-7.8.3.tgz"],
+ ["@babel/plugin-syntax-json-strings", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-json-strings%2Fdownload%2F%40babel%2Fplugin-syntax-json-strings-7.8.3.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1091,6 +1446,18 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-json-strings%2Fdownload%2F%40babel%2Fplugin-syntax-json-strings-7.8.3.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-json-strings-virtual-7f330c7b07/0/cache/@babel-plugin-syntax-json-strings-npm-7.8.3-ce7987f347-1a7dabf0a4.zip/node_modules/@babel/plugin-syntax-json-strings/",
+ "packageDependencies": [
+ ["@babel/plugin-syntax-json-strings", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-json-strings%2Fdownload%2F%40babel%2Fplugin-syntax-json-strings-7.8.3.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-syntax-jsx", [
@@ -1098,7 +1465,21 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-jsx-virtual-cf3ff66d85/0/cache/@babel-plugin-syntax-jsx-npm-7.10.4-5479ee1388-7c9a5c56e5.zip/node_modules/@babel/plugin-syntax-jsx/",
"packageDependencies": [
["@babel/plugin-syntax-jsx", "virtual:b90101bd8afda123e6c4ddd73f0f242aeabb99b76bf201038eabc91b1a8d0489b32520af3aa9f108ade2402c7b882bbf849a93b57b9b3340f68d73fa1729676d#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-jsx%2Fdownload%2F%40babel%2Fplugin-syntax-jsx-7.10.4.tgz"],
- ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }]
+ ]],
+ ["@babel/plugin-syntax-logical-assignment-operators", [
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-logical-assignment-operators%2Fdownload%2F%40babel%2Fplugin-syntax-logical-assignment-operators-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-logical-assignment-operators-virtual-eb0896d26e/0/cache/@babel-plugin-syntax-logical-assignment-operators-npm-7.10.4-35a8612a0a-5b82f71770.zip/node_modules/@babel/plugin-syntax-logical-assignment-operators/",
+ "packageDependencies": [
+ ["@babel/plugin-syntax-logical-assignment-operators", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-logical-assignment-operators%2Fdownload%2F%40babel%2Fplugin-syntax-logical-assignment-operators-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
"packagePeers": [
@@ -1108,11 +1489,23 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/plugin-syntax-nullish-coalescing-operator", [
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-nullish-coalescing-operator%2Fdownload%2F%40babel%2Fplugin-syntax-nullish-coalescing-operator-7.8.3.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-nullish-coalescing-operator-virtual-2fe57f12be/0/cache/@babel-plugin-syntax-nullish-coalescing-operator-npm-7.8.3-5740884dde-4ba0375375.zip/node_modules/@babel/plugin-syntax-nullish-coalescing-operator/",
+ "packageDependencies": [
+ ["@babel/plugin-syntax-nullish-coalescing-operator", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-nullish-coalescing-operator%2Fdownload%2F%40babel%2Fplugin-syntax-nullish-coalescing-operator-7.8.3.tgz"],
+ ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }],
["virtual:1aafd484e7c5739d9135bb3b82d8e863096fd061b8289a1e58fdc6707690db2c22912ae5275c7ec0ea6fb457d9aeba6d3d0f5d2e62cbebde76831d72dbc6b575#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-nullish-coalescing-operator%2Fdownload%2F%40babel%2Fplugin-syntax-nullish-coalescing-operator-7.8.3.tgz", {
"packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-nullish-coalescing-operator-virtual-1bc7011faf/0/cache/@babel-plugin-syntax-nullish-coalescing-operator-npm-7.8.3-5740884dde-4ba0375375.zip/node_modules/@babel/plugin-syntax-nullish-coalescing-operator/",
"packageDependencies": [
["@babel/plugin-syntax-nullish-coalescing-operator", "virtual:1aafd484e7c5739d9135bb3b82d8e863096fd061b8289a1e58fdc6707690db2c22912ae5275c7ec0ea6fb457d9aeba6d3d0f5d2e62cbebde76831d72dbc6b575#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-nullish-coalescing-operator%2Fdownload%2F%40babel%2Fplugin-syntax-nullish-coalescing-operator-7.8.3.tgz"],
- ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
"packagePeers": [
@@ -1122,10 +1515,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/plugin-syntax-numeric-separator", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-numeric-separator%2Fdownload%2F%40babel%2Fplugin-syntax-numeric-separator-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-numeric-separator-virtual-eed8b58a60/0/cache/@babel-plugin-syntax-numeric-separator-npm-7.10.4-1c8f950eaa-47ae878293.zip/node_modules/@babel/plugin-syntax-numeric-separator/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-numeric-separator%2Fdownload%2F%40babel%2Fplugin-syntax-numeric-separator-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-numeric-separator-virtual-4086511a1a/0/cache/@babel-plugin-syntax-numeric-separator-npm-7.10.4-1c8f950eaa-47ae878293.zip/node_modules/@babel/plugin-syntax-numeric-separator/",
"packageDependencies": [
- ["@babel/plugin-syntax-numeric-separator", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-numeric-separator%2Fdownload%2F%40babel%2Fplugin-syntax-numeric-separator-7.10.4.tgz"],
+ ["@babel/plugin-syntax-numeric-separator", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-numeric-separator%2Fdownload%2F%40babel%2Fplugin-syntax-numeric-separator-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1133,13 +1526,25 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-numeric-separator%2Fdownload%2F%40babel%2Fplugin-syntax-numeric-separator-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-numeric-separator-virtual-23ad3b2319/0/cache/@babel-plugin-syntax-numeric-separator-npm-7.10.4-1c8f950eaa-47ae878293.zip/node_modules/@babel/plugin-syntax-numeric-separator/",
+ "packageDependencies": [
+ ["@babel/plugin-syntax-numeric-separator", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-numeric-separator%2Fdownload%2F%40babel%2Fplugin-syntax-numeric-separator-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-syntax-object-rest-spread", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-syntax-object-rest-spread-7.8.3.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-object-rest-spread-virtual-19a79529c7/0/cache/@babel-plugin-syntax-object-rest-spread-npm-7.8.3-1c6d3f0524-db5dfb39fa.zip/node_modules/@babel/plugin-syntax-object-rest-spread/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-syntax-object-rest-spread-7.8.3.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-object-rest-spread-virtual-997eb0aafb/0/cache/@babel-plugin-syntax-object-rest-spread-npm-7.8.3-1c6d3f0524-db5dfb39fa.zip/node_modules/@babel/plugin-syntax-object-rest-spread/",
"packageDependencies": [
- ["@babel/plugin-syntax-object-rest-spread", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-syntax-object-rest-spread-7.8.3.tgz"],
+ ["@babel/plugin-syntax-object-rest-spread", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-syntax-object-rest-spread-7.8.3.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1147,13 +1552,25 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-syntax-object-rest-spread-7.8.3.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-object-rest-spread-virtual-d6d32cd810/0/cache/@babel-plugin-syntax-object-rest-spread-npm-7.8.3-1c6d3f0524-db5dfb39fa.zip/node_modules/@babel/plugin-syntax-object-rest-spread/",
+ "packageDependencies": [
+ ["@babel/plugin-syntax-object-rest-spread", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-syntax-object-rest-spread-7.8.3.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-syntax-optional-catch-binding", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-syntax-optional-catch-binding-7.8.3.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-optional-catch-binding-virtual-07360222c1/0/cache/@babel-plugin-syntax-optional-catch-binding-npm-7.8.3-6a0d3e7565-f03d075266.zip/node_modules/@babel/plugin-syntax-optional-catch-binding/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-syntax-optional-catch-binding-7.8.3.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-optional-catch-binding-virtual-986f4d7267/0/cache/@babel-plugin-syntax-optional-catch-binding-npm-7.8.3-6a0d3e7565-f03d075266.zip/node_modules/@babel/plugin-syntax-optional-catch-binding/",
"packageDependencies": [
- ["@babel/plugin-syntax-optional-catch-binding", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-syntax-optional-catch-binding-7.8.3.tgz"],
+ ["@babel/plugin-syntax-optional-catch-binding", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-syntax-optional-catch-binding-7.8.3.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1161,13 +1578,25 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-syntax-optional-catch-binding-7.8.3.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-optional-catch-binding-virtual-7cd7098181/0/cache/@babel-plugin-syntax-optional-catch-binding-npm-7.8.3-6a0d3e7565-f03d075266.zip/node_modules/@babel/plugin-syntax-optional-catch-binding/",
+ "packageDependencies": [
+ ["@babel/plugin-syntax-optional-catch-binding", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-syntax-optional-catch-binding-7.8.3.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-syntax-optional-chaining", [
- ["virtual:303da2bcf7cb54ecbdab5aadd757aceee31fcf731c58ada79b826235fd05987c4fd49cd36aa85ed9812896b79a14b330d14b59a9bb31b7a4f8a671b30938e476#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-chaining%2Fdownload%2F%40babel%2Fplugin-syntax-optional-chaining-7.8.3.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-optional-chaining-virtual-d745761ea9/0/cache/@babel-plugin-syntax-optional-chaining-npm-7.8.3-62970aee46-2a50685d02.zip/node_modules/@babel/plugin-syntax-optional-chaining/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-chaining%2Fdownload%2F%40babel%2Fplugin-syntax-optional-chaining-7.8.3.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-optional-chaining-virtual-fcbf97fe00/0/cache/@babel-plugin-syntax-optional-chaining-npm-7.8.3-62970aee46-2a50685d02.zip/node_modules/@babel/plugin-syntax-optional-chaining/",
"packageDependencies": [
- ["@babel/plugin-syntax-optional-chaining", "virtual:303da2bcf7cb54ecbdab5aadd757aceee31fcf731c58ada79b826235fd05987c4fd49cd36aa85ed9812896b79a14b330d14b59a9bb31b7a4f8a671b30938e476#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-chaining%2Fdownload%2F%40babel%2Fplugin-syntax-optional-chaining-7.8.3.tgz"],
+ ["@babel/plugin-syntax-optional-chaining", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-chaining%2Fdownload%2F%40babel%2Fplugin-syntax-optional-chaining-7.8.3.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1175,13 +1604,25 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:532709048cb003cd2417daa5fea56a95b3adea6f1c98f15bbeccd431c941ab5303512f56d976e8c33d619655e94e289d317ca2dbc731adc82d3687ee5a2dd94b#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-chaining%2Fdownload%2F%40babel%2Fplugin-syntax-optional-chaining-7.8.3.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-optional-chaining-virtual-b24230c9e2/0/cache/@babel-plugin-syntax-optional-chaining-npm-7.8.3-62970aee46-2a50685d02.zip/node_modules/@babel/plugin-syntax-optional-chaining/",
+ "packageDependencies": [
+ ["@babel/plugin-syntax-optional-chaining", "virtual:532709048cb003cd2417daa5fea56a95b3adea6f1c98f15bbeccd431c941ab5303512f56d976e8c33d619655e94e289d317ca2dbc731adc82d3687ee5a2dd94b#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-chaining%2Fdownload%2F%40babel%2Fplugin-syntax-optional-chaining-7.8.3.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-syntax-top-level-await", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-top-level-await%2Fdownload%2F%40babel%2Fplugin-syntax-top-level-await-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-top-level-await-virtual-df1e8dacb5/0/cache/@babel-plugin-syntax-top-level-await-npm-7.10.4-e4c4166480-998d87fbd3.zip/node_modules/@babel/plugin-syntax-top-level-await/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-top-level-await%2Fdownload%2F%40babel%2Fplugin-syntax-top-level-await-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-top-level-await-virtual-77db4d735d/0/cache/@babel-plugin-syntax-top-level-await-npm-7.10.4-e4c4166480-998d87fbd3.zip/node_modules/@babel/plugin-syntax-top-level-await/",
"packageDependencies": [
- ["@babel/plugin-syntax-top-level-await", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-top-level-await%2Fdownload%2F%40babel%2Fplugin-syntax-top-level-await-7.10.4.tgz"],
+ ["@babel/plugin-syntax-top-level-await", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-top-level-await%2Fdownload%2F%40babel%2Fplugin-syntax-top-level-await-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1189,6 +1630,18 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-top-level-await%2Fdownload%2F%40babel%2Fplugin-syntax-top-level-await-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-top-level-await-virtual-ba5c9d6c3f/0/cache/@babel-plugin-syntax-top-level-await-npm-7.10.4-e4c4166480-998d87fbd3.zip/node_modules/@babel/plugin-syntax-top-level-await/",
+ "packageDependencies": [
+ ["@babel/plugin-syntax-top-level-await", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-top-level-await%2Fdownload%2F%40babel%2Fplugin-syntax-top-level-await-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-syntax-typescript", [
@@ -1196,7 +1649,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./.yarn/$$virtual/@babel-plugin-syntax-typescript-virtual-36aec08341/0/cache/@babel-plugin-syntax-typescript-npm-7.10.4-d7f1c0d10b-9511691ac0.zip/node_modules/@babel/plugin-syntax-typescript/",
"packageDependencies": [
["@babel/plugin-syntax-typescript", "virtual:b2bda0916789a79a30759540ac5b83df187fa32f9233c09c0178a4a113d8a478f18f47cf1cad69d5fa966f1e94861b3c726ec222eb41f27ac6ee65b2acfa9c97#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-typescript%2Fdownload%2F%40babel%2Fplugin-syntax-typescript-7.10.4.tgz"],
- ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
"packagePeers": [
@@ -1206,10 +1659,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/plugin-transform-arrow-functions", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-arrow-functions%2Fdownload%2F%40babel%2Fplugin-transform-arrow-functions-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-arrow-functions-virtual-3d7e3cc182/0/cache/@babel-plugin-transform-arrow-functions-npm-7.10.4-dcee1b623d-ec5b1d6ec6.zip/node_modules/@babel/plugin-transform-arrow-functions/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-arrow-functions%2Fdownload%2F%40babel%2Fplugin-transform-arrow-functions-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-arrow-functions-virtual-39c9963591/0/cache/@babel-plugin-transform-arrow-functions-npm-7.10.4-dcee1b623d-ec5b1d6ec6.zip/node_modules/@babel/plugin-transform-arrow-functions/",
"packageDependencies": [
- ["@babel/plugin-transform-arrow-functions", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-arrow-functions%2Fdownload%2F%40babel%2Fplugin-transform-arrow-functions-7.10.4.tgz"],
+ ["@babel/plugin-transform-arrow-functions", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-arrow-functions%2Fdownload%2F%40babel%2Fplugin-transform-arrow-functions-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1217,13 +1670,25 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-arrow-functions%2Fdownload%2F%40babel%2Fplugin-transform-arrow-functions-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-arrow-functions-virtual-418b1831f3/0/cache/@babel-plugin-transform-arrow-functions-npm-7.10.4-dcee1b623d-ec5b1d6ec6.zip/node_modules/@babel/plugin-transform-arrow-functions/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-arrow-functions", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-arrow-functions%2Fdownload%2F%40babel%2Fplugin-transform-arrow-functions-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-async-to-generator", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-async-to-generator%2Fdownload%2F%40babel%2Fplugin-transform-async-to-generator-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-async-to-generator-virtual-b7693183f6/0/cache/@babel-plugin-transform-async-to-generator-npm-7.10.4-5de1d3a103-c4cddae691.zip/node_modules/@babel/plugin-transform-async-to-generator/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-async-to-generator%2Fdownload%2F%40babel%2Fplugin-transform-async-to-generator-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-async-to-generator-virtual-9064f1feda/0/cache/@babel-plugin-transform-async-to-generator-npm-7.10.4-5de1d3a103-c4cddae691.zip/node_modules/@babel/plugin-transform-async-to-generator/",
"packageDependencies": [
- ["@babel/plugin-transform-async-to-generator", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-async-to-generator%2Fdownload%2F%40babel%2Fplugin-transform-async-to-generator-7.10.4.tgz"],
+ ["@babel/plugin-transform-async-to-generator", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-async-to-generator%2Fdownload%2F%40babel%2Fplugin-transform-async-to-generator-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-module-imports", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-imports%2Fdownload%2F%40babel%2Fhelper-module-imports-7.10.4.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
@@ -1233,13 +1698,27 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-async-to-generator%2Fdownload%2F%40babel%2Fplugin-transform-async-to-generator-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-async-to-generator-virtual-4b351fedb2/0/cache/@babel-plugin-transform-async-to-generator-npm-7.10.4-5de1d3a103-c4cddae691.zip/node_modules/@babel/plugin-transform-async-to-generator/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-async-to-generator", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-async-to-generator%2Fdownload%2F%40babel%2Fplugin-transform-async-to-generator-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-module-imports", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-imports%2Fdownload%2F%40babel%2Fhelper-module-imports-7.10.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
+ ["@babel/helper-remap-async-to-generator", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-remap-async-to-generator%2Fdownload%2F%40babel%2Fhelper-remap-async-to-generator-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-block-scoped-functions", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoped-functions%2Fdownload%2F%40babel%2Fplugin-transform-block-scoped-functions-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-block-scoped-functions-virtual-1582f8d4a1/0/cache/@babel-plugin-transform-block-scoped-functions-npm-7.10.4-6787915d0b-d608f55104.zip/node_modules/@babel/plugin-transform-block-scoped-functions/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoped-functions%2Fdownload%2F%40babel%2Fplugin-transform-block-scoped-functions-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-block-scoped-functions-virtual-d1c4ade98b/0/cache/@babel-plugin-transform-block-scoped-functions-npm-7.10.4-6787915d0b-d608f55104.zip/node_modules/@babel/plugin-transform-block-scoped-functions/",
"packageDependencies": [
- ["@babel/plugin-transform-block-scoped-functions", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoped-functions%2Fdownload%2F%40babel%2Fplugin-transform-block-scoped-functions-7.10.4.tgz"],
+ ["@babel/plugin-transform-block-scoped-functions", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoped-functions%2Fdownload%2F%40babel%2Fplugin-transform-block-scoped-functions-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1247,13 +1726,25 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoped-functions%2Fdownload%2F%40babel%2Fplugin-transform-block-scoped-functions-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-block-scoped-functions-virtual-49034f8f80/0/cache/@babel-plugin-transform-block-scoped-functions-npm-7.10.4-6787915d0b-d608f55104.zip/node_modules/@babel/plugin-transform-block-scoped-functions/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-block-scoped-functions", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoped-functions%2Fdownload%2F%40babel%2Fplugin-transform-block-scoped-functions-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-block-scoping", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoping%2Fdownload%2F%40babel%2Fplugin-transform-block-scoping-7.10.5.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-block-scoping-virtual-46e7c2390c/0/cache/@babel-plugin-transform-block-scoping-npm-7.10.5-85771bcdae-f4df58ebe8.zip/node_modules/@babel/plugin-transform-block-scoping/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoping%2Fdownload%2F%40babel%2Fplugin-transform-block-scoping-7.10.5.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-block-scoping-virtual-562e2fd37f/0/cache/@babel-plugin-transform-block-scoping-npm-7.10.5-85771bcdae-f4df58ebe8.zip/node_modules/@babel/plugin-transform-block-scoping/",
"packageDependencies": [
- ["@babel/plugin-transform-block-scoping", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoping%2Fdownload%2F%40babel%2Fplugin-transform-block-scoping-7.10.5.tgz"],
+ ["@babel/plugin-transform-block-scoping", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoping%2Fdownload%2F%40babel%2Fplugin-transform-block-scoping-7.10.5.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1261,13 +1752,25 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoping%2Fdownload%2F%40babel%2Fplugin-transform-block-scoping-7.10.5.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-block-scoping-virtual-d2c3704cb9/0/cache/@babel-plugin-transform-block-scoping-npm-7.10.5-85771bcdae-f4df58ebe8.zip/node_modules/@babel/plugin-transform-block-scoping/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-block-scoping", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoping%2Fdownload%2F%40babel%2Fplugin-transform-block-scoping-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-classes", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-classes%2Fdownload%2F%40babel%2Fplugin-transform-classes-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-classes-virtual-83ecba591c/0/cache/@babel-plugin-transform-classes-npm-7.10.4-d22e940336-c5ba85f736.zip/node_modules/@babel/plugin-transform-classes/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-classes%2Fdownload%2F%40babel%2Fplugin-transform-classes-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-classes-virtual-9561ed2ec8/0/cache/@babel-plugin-transform-classes-npm-7.10.4-d22e940336-c5ba85f736.zip/node_modules/@babel/plugin-transform-classes/",
"packageDependencies": [
- ["@babel/plugin-transform-classes", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-classes%2Fdownload%2F%40babel%2Fplugin-transform-classes-7.10.4.tgz"],
+ ["@babel/plugin-transform-classes", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-classes%2Fdownload%2F%40babel%2Fplugin-transform-classes-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-annotate-as-pure", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-annotate-as-pure%2Fdownload%2F%40babel%2Fhelper-annotate-as-pure-7.10.4.tgz"],
["@babel/helper-define-map", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-define-map%2Fdownload%2F%40babel%2Fhelper-define-map-7.10.5.tgz"],
@@ -1282,13 +1785,32 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-classes%2Fdownload%2F%40babel%2Fplugin-transform-classes-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-classes-virtual-bc866da18c/0/cache/@babel-plugin-transform-classes-npm-7.10.4-d22e940336-c5ba85f736.zip/node_modules/@babel/plugin-transform-classes/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-classes", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-classes%2Fdownload%2F%40babel%2Fplugin-transform-classes-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-annotate-as-pure", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-annotate-as-pure%2Fdownload%2F%40babel%2Fhelper-annotate-as-pure-7.10.4.tgz"],
+ ["@babel/helper-define-map", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-define-map%2Fdownload%2F%40babel%2Fhelper-define-map-7.10.5.tgz"],
+ ["@babel/helper-function-name", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-function-name%2Fdownload%2F%40babel%2Fhelper-function-name-7.10.4.tgz"],
+ ["@babel/helper-optimise-call-expression", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-optimise-call-expression%2Fdownload%2F%40babel%2Fhelper-optimise-call-expression-7.10.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
+ ["@babel/helper-replace-supers", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-replace-supers%2Fdownload%2F%40babel%2Fhelper-replace-supers-7.10.4.tgz"],
+ ["@babel/helper-split-export-declaration", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-split-export-declaration%2Fdownload%2F%40babel%2Fhelper-split-export-declaration-7.10.4.tgz"],
+ ["globals", "npm:11.12.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fglobals%2Fdownload%2Fglobals-11.12.0.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-computed-properties", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-computed-properties%2Fdownload%2F%40babel%2Fplugin-transform-computed-properties-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-computed-properties-virtual-415670ee6c/0/cache/@babel-plugin-transform-computed-properties-npm-7.10.4-5acbc51c51-c69c53881d.zip/node_modules/@babel/plugin-transform-computed-properties/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-computed-properties%2Fdownload%2F%40babel%2Fplugin-transform-computed-properties-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-computed-properties-virtual-e7645f428e/0/cache/@babel-plugin-transform-computed-properties-npm-7.10.4-5acbc51c51-c69c53881d.zip/node_modules/@babel/plugin-transform-computed-properties/",
"packageDependencies": [
- ["@babel/plugin-transform-computed-properties", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-computed-properties%2Fdownload%2F%40babel%2Fplugin-transform-computed-properties-7.10.4.tgz"],
+ ["@babel/plugin-transform-computed-properties", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-computed-properties%2Fdownload%2F%40babel%2Fplugin-transform-computed-properties-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1296,13 +1818,25 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-computed-properties%2Fdownload%2F%40babel%2Fplugin-transform-computed-properties-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-computed-properties-virtual-936030f4ef/0/cache/@babel-plugin-transform-computed-properties-npm-7.10.4-5acbc51c51-c69c53881d.zip/node_modules/@babel/plugin-transform-computed-properties/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-computed-properties", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-computed-properties%2Fdownload%2F%40babel%2Fplugin-transform-computed-properties-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-destructuring", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-destructuring%2Fdownload%2F%40babel%2Fplugin-transform-destructuring-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-destructuring-virtual-1c1e01d65c/0/cache/@babel-plugin-transform-destructuring-npm-7.10.4-ef79524275-2ea7148346.zip/node_modules/@babel/plugin-transform-destructuring/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-destructuring%2Fdownload%2F%40babel%2Fplugin-transform-destructuring-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-destructuring-virtual-d9f772f4fe/0/cache/@babel-plugin-transform-destructuring-npm-7.10.4-ef79524275-2ea7148346.zip/node_modules/@babel/plugin-transform-destructuring/",
"packageDependencies": [
- ["@babel/plugin-transform-destructuring", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-destructuring%2Fdownload%2F%40babel%2Fplugin-transform-destructuring-7.10.4.tgz"],
+ ["@babel/plugin-transform-destructuring", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-destructuring%2Fdownload%2F%40babel%2Fplugin-transform-destructuring-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1310,15 +1844,40 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-destructuring%2Fdownload%2F%40babel%2Fplugin-transform-destructuring-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-destructuring-virtual-178711181e/0/cache/@babel-plugin-transform-destructuring-npm-7.10.4-ef79524275-2ea7148346.zip/node_modules/@babel/plugin-transform-destructuring/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-destructuring", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-destructuring%2Fdownload%2F%40babel%2Fplugin-transform-destructuring-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-dotall-regex", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-dotall-regex%2Fdownload%2F%40babel%2Fplugin-transform-dotall-regex-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-dotall-regex-virtual-29c6bba97e/0/cache/@babel-plugin-transform-dotall-regex-npm-7.10.4-0168d189ac-284cce72df.zip/node_modules/@babel/plugin-transform-dotall-regex/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-dotall-regex%2Fdownload%2F%40babel%2Fplugin-transform-dotall-regex-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-dotall-regex-virtual-4923eece2b/0/cache/@babel-plugin-transform-dotall-regex-npm-7.10.4-0168d189ac-284cce72df.zip/node_modules/@babel/plugin-transform-dotall-regex/",
"packageDependencies": [
- ["@babel/plugin-transform-dotall-regex", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-dotall-regex%2Fdownload%2F%40babel%2Fplugin-transform-dotall-regex-7.10.4.tgz"],
+ ["@babel/plugin-transform-dotall-regex", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-dotall-regex%2Fdownload%2F%40babel%2Fplugin-transform-dotall-regex-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
- ["@babel/helper-create-regexp-features-plugin", "virtual:4e95dff1e4d799ff1ad5b1d72fb9e856f303a7db3c862cc93ca2390c538394d4a4a141e0cac4effa2a8dba9bf2e598221f9095418d8d91d03b81ae16281a991b#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-regexp-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-regexp-features-plugin-7.10.4.tgz"],
+ ["@babel/helper-create-regexp-features-plugin", "virtual:603d46702a42ce5c1028458dccd33e2fb1f5c8827f04e28a6705e7321c377b2ceab089d1924f8dc9a3517025ec0466db221bd611c0c591fb724085dc966cc3fc#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-regexp-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-regexp-features-plugin-7.10.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-dotall-regex%2Fdownload%2F%40babel%2Fplugin-transform-dotall-regex-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-dotall-regex-virtual-74a1d1dbe4/0/cache/@babel-plugin-transform-dotall-regex-npm-7.10.4-0168d189ac-284cce72df.zip/node_modules/@babel/plugin-transform-dotall-regex/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-dotall-regex", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-dotall-regex%2Fdownload%2F%40babel%2Fplugin-transform-dotall-regex-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-create-regexp-features-plugin", "virtual:cb2dd087c703ec7307b541f992f3886d88eb72680bfa1ed88da28ff8b65d87d95e29d9e038cf20b422f8c09e4062de4c8890d7150f32e96e4d9866ffa2fdb838#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-regexp-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-regexp-features-plugin-7.10.4.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
"packagePeers": [
@@ -1328,10 +1887,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/plugin-transform-duplicate-keys", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-duplicate-keys%2Fdownload%2F%40babel%2Fplugin-transform-duplicate-keys-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-duplicate-keys-virtual-49603afcf2/0/cache/@babel-plugin-transform-duplicate-keys-npm-7.10.4-cea8ef411f-60897c7c2f.zip/node_modules/@babel/plugin-transform-duplicate-keys/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-duplicate-keys%2Fdownload%2F%40babel%2Fplugin-transform-duplicate-keys-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-duplicate-keys-virtual-ac7d960533/0/cache/@babel-plugin-transform-duplicate-keys-npm-7.10.4-cea8ef411f-60897c7c2f.zip/node_modules/@babel/plugin-transform-duplicate-keys/",
"packageDependencies": [
- ["@babel/plugin-transform-duplicate-keys", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-duplicate-keys%2Fdownload%2F%40babel%2Fplugin-transform-duplicate-keys-7.10.4.tgz"],
+ ["@babel/plugin-transform-duplicate-keys", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-duplicate-keys%2Fdownload%2F%40babel%2Fplugin-transform-duplicate-keys-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1339,13 +1898,25 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-duplicate-keys%2Fdownload%2F%40babel%2Fplugin-transform-duplicate-keys-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-duplicate-keys-virtual-86d785e73d/0/cache/@babel-plugin-transform-duplicate-keys-npm-7.10.4-cea8ef411f-60897c7c2f.zip/node_modules/@babel/plugin-transform-duplicate-keys/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-duplicate-keys", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-duplicate-keys%2Fdownload%2F%40babel%2Fplugin-transform-duplicate-keys-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-exponentiation-operator", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-exponentiation-operator%2Fdownload%2F%40babel%2Fplugin-transform-exponentiation-operator-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-exponentiation-operator-virtual-422e29f7d2/0/cache/@babel-plugin-transform-exponentiation-operator-npm-7.10.4-9862c4be23-fb086b4482.zip/node_modules/@babel/plugin-transform-exponentiation-operator/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-exponentiation-operator%2Fdownload%2F%40babel%2Fplugin-transform-exponentiation-operator-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-exponentiation-operator-virtual-121877d1ea/0/cache/@babel-plugin-transform-exponentiation-operator-npm-7.10.4-9862c4be23-fb086b4482.zip/node_modules/@babel/plugin-transform-exponentiation-operator/",
"packageDependencies": [
- ["@babel/plugin-transform-exponentiation-operator", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-exponentiation-operator%2Fdownload%2F%40babel%2Fplugin-transform-exponentiation-operator-7.10.4.tgz"],
+ ["@babel/plugin-transform-exponentiation-operator", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-exponentiation-operator%2Fdownload%2F%40babel%2Fplugin-transform-exponentiation-operator-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-builder-binary-assignment-operator-visitor", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-builder-binary-assignment-operator-visitor%2Fdownload%2F%40babel%2Fhelper-builder-binary-assignment-operator-visitor-7.10.4.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
@@ -1354,13 +1925,26 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-exponentiation-operator%2Fdownload%2F%40babel%2Fplugin-transform-exponentiation-operator-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-exponentiation-operator-virtual-b673cb84a8/0/cache/@babel-plugin-transform-exponentiation-operator-npm-7.10.4-9862c4be23-fb086b4482.zip/node_modules/@babel/plugin-transform-exponentiation-operator/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-exponentiation-operator", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-exponentiation-operator%2Fdownload%2F%40babel%2Fplugin-transform-exponentiation-operator-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-builder-binary-assignment-operator-visitor", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-builder-binary-assignment-operator-visitor%2Fdownload%2F%40babel%2Fhelper-builder-binary-assignment-operator-visitor-7.10.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-for-of", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-for-of%2Fdownload%2F%40babel%2Fplugin-transform-for-of-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-for-of-virtual-3b64a478b3/0/cache/@babel-plugin-transform-for-of-npm-7.10.4-552f4d0a73-86c02bbf98.zip/node_modules/@babel/plugin-transform-for-of/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-for-of%2Fdownload%2F%40babel%2Fplugin-transform-for-of-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-for-of-virtual-8ca312e1b7/0/cache/@babel-plugin-transform-for-of-npm-7.10.4-552f4d0a73-86c02bbf98.zip/node_modules/@babel/plugin-transform-for-of/",
"packageDependencies": [
- ["@babel/plugin-transform-for-of", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-for-of%2Fdownload%2F%40babel%2Fplugin-transform-for-of-7.10.4.tgz"],
+ ["@babel/plugin-transform-for-of", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-for-of%2Fdownload%2F%40babel%2Fplugin-transform-for-of-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1368,13 +1952,25 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-for-of%2Fdownload%2F%40babel%2Fplugin-transform-for-of-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-for-of-virtual-1580b879f5/0/cache/@babel-plugin-transform-for-of-npm-7.10.4-552f4d0a73-86c02bbf98.zip/node_modules/@babel/plugin-transform-for-of/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-for-of", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-for-of%2Fdownload%2F%40babel%2Fplugin-transform-for-of-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-function-name", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-function-name%2Fdownload%2F%40babel%2Fplugin-transform-function-name-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-function-name-virtual-dd45d57ab4/0/cache/@babel-plugin-transform-function-name-npm-7.10.4-3d9bd4cc22-64d8bf2de2.zip/node_modules/@babel/plugin-transform-function-name/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-function-name%2Fdownload%2F%40babel%2Fplugin-transform-function-name-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-function-name-virtual-d93ca341a7/0/cache/@babel-plugin-transform-function-name-npm-7.10.4-3d9bd4cc22-64d8bf2de2.zip/node_modules/@babel/plugin-transform-function-name/",
"packageDependencies": [
- ["@babel/plugin-transform-function-name", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-function-name%2Fdownload%2F%40babel%2Fplugin-transform-function-name-7.10.4.tgz"],
+ ["@babel/plugin-transform-function-name", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-function-name%2Fdownload%2F%40babel%2Fplugin-transform-function-name-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-function-name", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-function-name%2Fdownload%2F%40babel%2Fhelper-function-name-7.10.4.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
@@ -1383,13 +1979,26 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-function-name%2Fdownload%2F%40babel%2Fplugin-transform-function-name-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-function-name-virtual-5e6b41337f/0/cache/@babel-plugin-transform-function-name-npm-7.10.4-3d9bd4cc22-64d8bf2de2.zip/node_modules/@babel/plugin-transform-function-name/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-function-name", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-function-name%2Fdownload%2F%40babel%2Fplugin-transform-function-name-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-function-name", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-function-name%2Fdownload%2F%40babel%2Fhelper-function-name-7.10.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-literals", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-literals%2Fdownload%2F%40babel%2Fplugin-transform-literals-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-literals-virtual-1f12480956/0/cache/@babel-plugin-transform-literals-npm-7.10.4-a34bf6f972-53cd3f4367.zip/node_modules/@babel/plugin-transform-literals/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-literals%2Fdownload%2F%40babel%2Fplugin-transform-literals-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-literals-virtual-34b3e1fbc7/0/cache/@babel-plugin-transform-literals-npm-7.10.4-a34bf6f972-53cd3f4367.zip/node_modules/@babel/plugin-transform-literals/",
"packageDependencies": [
- ["@babel/plugin-transform-literals", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-literals%2Fdownload%2F%40babel%2Fplugin-transform-literals-7.10.4.tgz"],
+ ["@babel/plugin-transform-literals", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-literals%2Fdownload%2F%40babel%2Fplugin-transform-literals-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1397,13 +2006,25 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-literals%2Fdownload%2F%40babel%2Fplugin-transform-literals-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-literals-virtual-9eade4cc9d/0/cache/@babel-plugin-transform-literals-npm-7.10.4-a34bf6f972-53cd3f4367.zip/node_modules/@babel/plugin-transform-literals/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-literals", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-literals%2Fdownload%2F%40babel%2Fplugin-transform-literals-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-member-expression-literals", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-member-expression-literals%2Fdownload%2F%40babel%2Fplugin-transform-member-expression-literals-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-member-expression-literals-virtual-c2e2f943a6/0/cache/@babel-plugin-transform-member-expression-literals-npm-7.10.4-ec6b2ea122-e6a1844cb5.zip/node_modules/@babel/plugin-transform-member-expression-literals/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-member-expression-literals%2Fdownload%2F%40babel%2Fplugin-transform-member-expression-literals-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-member-expression-literals-virtual-7f366997ea/0/cache/@babel-plugin-transform-member-expression-literals-npm-7.10.4-ec6b2ea122-e6a1844cb5.zip/node_modules/@babel/plugin-transform-member-expression-literals/",
"packageDependencies": [
- ["@babel/plugin-transform-member-expression-literals", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-member-expression-literals%2Fdownload%2F%40babel%2Fplugin-transform-member-expression-literals-7.10.4.tgz"],
+ ["@babel/plugin-transform-member-expression-literals", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-member-expression-literals%2Fdownload%2F%40babel%2Fplugin-transform-member-expression-literals-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1411,13 +2032,25 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-member-expression-literals%2Fdownload%2F%40babel%2Fplugin-transform-member-expression-literals-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-member-expression-literals-virtual-e70ba349ad/0/cache/@babel-plugin-transform-member-expression-literals-npm-7.10.4-ec6b2ea122-e6a1844cb5.zip/node_modules/@babel/plugin-transform-member-expression-literals/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-member-expression-literals", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-member-expression-literals%2Fdownload%2F%40babel%2Fplugin-transform-member-expression-literals-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-modules-amd", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-amd%2Fdownload%2F%40babel%2Fplugin-transform-modules-amd-7.10.5.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-modules-amd-virtual-37d31167ec/0/cache/@babel-plugin-transform-modules-amd-npm-7.10.5-8b6244dc4f-6d2b80f3ca.zip/node_modules/@babel/plugin-transform-modules-amd/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-amd%2Fdownload%2F%40babel%2Fplugin-transform-modules-amd-7.10.5.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-modules-amd-virtual-97497b675b/0/cache/@babel-plugin-transform-modules-amd-npm-7.10.5-8b6244dc4f-6d2b80f3ca.zip/node_modules/@babel/plugin-transform-modules-amd/",
"packageDependencies": [
- ["@babel/plugin-transform-modules-amd", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-amd%2Fdownload%2F%40babel%2Fplugin-transform-modules-amd-7.10.5.tgz"],
+ ["@babel/plugin-transform-modules-amd", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-amd%2Fdownload%2F%40babel%2Fplugin-transform-modules-amd-7.10.5.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-module-transforms", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-transforms%2Fdownload%2F%40babel%2Fhelper-module-transforms-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
@@ -1427,13 +2060,27 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-amd%2Fdownload%2F%40babel%2Fplugin-transform-modules-amd-7.10.5.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-modules-amd-virtual-7e4b6e23c7/0/cache/@babel-plugin-transform-modules-amd-npm-7.10.5-8b6244dc4f-6d2b80f3ca.zip/node_modules/@babel/plugin-transform-modules-amd/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-modules-amd", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-amd%2Fdownload%2F%40babel%2Fplugin-transform-modules-amd-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-module-transforms", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-transforms%2Fdownload%2F%40babel%2Fhelper-module-transforms-7.10.5.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
+ ["babel-plugin-dynamic-import-node", "npm:2.3.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-plugin-dynamic-import-node%2Fdownload%2Fbabel-plugin-dynamic-import-node-2.3.3.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-modules-commonjs", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-commonjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-commonjs-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-modules-commonjs-virtual-37669cf1e8/0/cache/@babel-plugin-transform-modules-commonjs-npm-7.10.4-3e7497f7dd-4217686508.zip/node_modules/@babel/plugin-transform-modules-commonjs/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-commonjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-commonjs-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-modules-commonjs-virtual-3de6b67fd7/0/cache/@babel-plugin-transform-modules-commonjs-npm-7.10.4-3e7497f7dd-4217686508.zip/node_modules/@babel/plugin-transform-modules-commonjs/",
"packageDependencies": [
- ["@babel/plugin-transform-modules-commonjs", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-commonjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-commonjs-7.10.4.tgz"],
+ ["@babel/plugin-transform-modules-commonjs", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-commonjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-commonjs-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-module-transforms", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-transforms%2Fdownload%2F%40babel%2Fhelper-module-transforms-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
@@ -1444,13 +2091,28 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-commonjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-commonjs-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-modules-commonjs-virtual-d7ae9f3d40/0/cache/@babel-plugin-transform-modules-commonjs-npm-7.10.4-3e7497f7dd-4217686508.zip/node_modules/@babel/plugin-transform-modules-commonjs/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-modules-commonjs", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-commonjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-commonjs-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-module-transforms", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-transforms%2Fdownload%2F%40babel%2Fhelper-module-transforms-7.10.5.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
+ ["@babel/helper-simple-access", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-simple-access%2Fdownload%2F%40babel%2Fhelper-simple-access-7.10.4.tgz"],
+ ["babel-plugin-dynamic-import-node", "npm:2.3.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-plugin-dynamic-import-node%2Fdownload%2Fbabel-plugin-dynamic-import-node-2.3.3.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-modules-systemjs", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-systemjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-systemjs-7.10.5.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-modules-systemjs-virtual-ca8dace7d7/0/cache/@babel-plugin-transform-modules-systemjs-npm-7.10.5-1a8c89fe70-eb08d7c7e5.zip/node_modules/@babel/plugin-transform-modules-systemjs/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-systemjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-systemjs-7.10.5.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-modules-systemjs-virtual-722d59bc58/0/cache/@babel-plugin-transform-modules-systemjs-npm-7.10.5-1a8c89fe70-eb08d7c7e5.zip/node_modules/@babel/plugin-transform-modules-systemjs/",
"packageDependencies": [
- ["@babel/plugin-transform-modules-systemjs", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-systemjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-systemjs-7.10.5.tgz"],
+ ["@babel/plugin-transform-modules-systemjs", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-systemjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-systemjs-7.10.5.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-hoist-variables", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-hoist-variables%2Fdownload%2F%40babel%2Fhelper-hoist-variables-7.10.4.tgz"],
["@babel/helper-module-transforms", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-transforms%2Fdownload%2F%40babel%2Fhelper-module-transforms-7.10.5.tgz"],
@@ -1461,13 +2123,28 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-systemjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-systemjs-7.10.5.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-modules-systemjs-virtual-1564ac9bce/0/cache/@babel-plugin-transform-modules-systemjs-npm-7.10.5-1a8c89fe70-eb08d7c7e5.zip/node_modules/@babel/plugin-transform-modules-systemjs/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-modules-systemjs", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-systemjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-systemjs-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-hoist-variables", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-hoist-variables%2Fdownload%2F%40babel%2Fhelper-hoist-variables-7.10.4.tgz"],
+ ["@babel/helper-module-transforms", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-transforms%2Fdownload%2F%40babel%2Fhelper-module-transforms-7.10.5.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
+ ["babel-plugin-dynamic-import-node", "npm:2.3.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-plugin-dynamic-import-node%2Fdownload%2Fbabel-plugin-dynamic-import-node-2.3.3.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-modules-umd", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-umd%2Fdownload%2F%40babel%2Fplugin-transform-modules-umd-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-modules-umd-virtual-aace267bf4/0/cache/@babel-plugin-transform-modules-umd-npm-7.10.4-285f5a9cb0-b0c3f47b9e.zip/node_modules/@babel/plugin-transform-modules-umd/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-umd%2Fdownload%2F%40babel%2Fplugin-transform-modules-umd-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-modules-umd-virtual-5e05fb8cb1/0/cache/@babel-plugin-transform-modules-umd-npm-7.10.4-285f5a9cb0-b0c3f47b9e.zip/node_modules/@babel/plugin-transform-modules-umd/",
"packageDependencies": [
- ["@babel/plugin-transform-modules-umd", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-umd%2Fdownload%2F%40babel%2Fplugin-transform-modules-umd-7.10.4.tgz"],
+ ["@babel/plugin-transform-modules-umd", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-umd%2Fdownload%2F%40babel%2Fplugin-transform-modules-umd-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-module-transforms", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-transforms%2Fdownload%2F%40babel%2Fhelper-module-transforms-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
@@ -1476,15 +2153,40 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-umd%2Fdownload%2F%40babel%2Fplugin-transform-modules-umd-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-modules-umd-virtual-71327585c6/0/cache/@babel-plugin-transform-modules-umd-npm-7.10.4-285f5a9cb0-b0c3f47b9e.zip/node_modules/@babel/plugin-transform-modules-umd/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-modules-umd", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-umd%2Fdownload%2F%40babel%2Fplugin-transform-modules-umd-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-module-transforms", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-transforms%2Fdownload%2F%40babel%2Fhelper-module-transforms-7.10.5.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-named-capturing-groups-regex", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-named-capturing-groups-regex%2Fdownload%2F%40babel%2Fplugin-transform-named-capturing-groups-regex-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-named-capturing-groups-regex-virtual-0bf085e60c/0/cache/@babel-plugin-transform-named-capturing-groups-regex-npm-7.10.4-1a1a108814-6b868806fd.zip/node_modules/@babel/plugin-transform-named-capturing-groups-regex/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-named-capturing-groups-regex%2Fdownload%2F%40babel%2Fplugin-transform-named-capturing-groups-regex-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-named-capturing-groups-regex-virtual-a072aa0c4f/0/cache/@babel-plugin-transform-named-capturing-groups-regex-npm-7.10.4-1a1a108814-6b868806fd.zip/node_modules/@babel/plugin-transform-named-capturing-groups-regex/",
"packageDependencies": [
- ["@babel/plugin-transform-named-capturing-groups-regex", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-named-capturing-groups-regex%2Fdownload%2F%40babel%2Fplugin-transform-named-capturing-groups-regex-7.10.4.tgz"],
+ ["@babel/plugin-transform-named-capturing-groups-regex", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-named-capturing-groups-regex%2Fdownload%2F%40babel%2Fplugin-transform-named-capturing-groups-regex-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
- ["@babel/helper-create-regexp-features-plugin", "virtual:4e95dff1e4d799ff1ad5b1d72fb9e856f303a7db3c862cc93ca2390c538394d4a4a141e0cac4effa2a8dba9bf2e598221f9095418d8d91d03b81ae16281a991b#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-regexp-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-regexp-features-plugin-7.10.4.tgz"]
+ ["@babel/helper-create-regexp-features-plugin", "virtual:603d46702a42ce5c1028458dccd33e2fb1f5c8827f04e28a6705e7321c377b2ceab089d1924f8dc9a3517025ec0466db221bd611c0c591fb724085dc966cc3fc#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-regexp-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-regexp-features-plugin-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-named-capturing-groups-regex%2Fdownload%2F%40babel%2Fplugin-transform-named-capturing-groups-regex-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-named-capturing-groups-regex-virtual-17e19a6aa9/0/cache/@babel-plugin-transform-named-capturing-groups-regex-npm-7.10.4-1a1a108814-6b868806fd.zip/node_modules/@babel/plugin-transform-named-capturing-groups-regex/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-named-capturing-groups-regex", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-named-capturing-groups-regex%2Fdownload%2F%40babel%2Fplugin-transform-named-capturing-groups-regex-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-create-regexp-features-plugin", "virtual:cb2dd087c703ec7307b541f992f3886d88eb72680bfa1ed88da28ff8b65d87d95e29d9e038cf20b422f8c09e4062de4c8890d7150f32e96e4d9866ffa2fdb838#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-regexp-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-regexp-features-plugin-7.10.4.tgz"]
],
"packagePeers": [
"@babel/core"
@@ -1493,10 +2195,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/plugin-transform-new-target", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-new-target%2Fdownload%2F%40babel%2Fplugin-transform-new-target-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-new-target-virtual-ec0b8a6d5f/0/cache/@babel-plugin-transform-new-target-npm-7.10.4-10b38ec6b0-a4742428d2.zip/node_modules/@babel/plugin-transform-new-target/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-new-target%2Fdownload%2F%40babel%2Fplugin-transform-new-target-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-new-target-virtual-abb4c891e6/0/cache/@babel-plugin-transform-new-target-npm-7.10.4-10b38ec6b0-a4742428d2.zip/node_modules/@babel/plugin-transform-new-target/",
"packageDependencies": [
- ["@babel/plugin-transform-new-target", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-new-target%2Fdownload%2F%40babel%2Fplugin-transform-new-target-7.10.4.tgz"],
+ ["@babel/plugin-transform-new-target", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-new-target%2Fdownload%2F%40babel%2Fplugin-transform-new-target-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1504,13 +2206,25 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-new-target%2Fdownload%2F%40babel%2Fplugin-transform-new-target-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-new-target-virtual-d5ba50b211/0/cache/@babel-plugin-transform-new-target-npm-7.10.4-10b38ec6b0-a4742428d2.zip/node_modules/@babel/plugin-transform-new-target/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-new-target", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-new-target%2Fdownload%2F%40babel%2Fplugin-transform-new-target-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-object-super", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-object-super%2Fdownload%2F%40babel%2Fplugin-transform-object-super-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-object-super-virtual-033703b41a/0/cache/@babel-plugin-transform-object-super-npm-7.10.4-9ec43ad72e-30485dd88b.zip/node_modules/@babel/plugin-transform-object-super/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-object-super%2Fdownload%2F%40babel%2Fplugin-transform-object-super-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-object-super-virtual-d50b6d1541/0/cache/@babel-plugin-transform-object-super-npm-7.10.4-9ec43ad72e-30485dd88b.zip/node_modules/@babel/plugin-transform-object-super/",
"packageDependencies": [
- ["@babel/plugin-transform-object-super", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-object-super%2Fdownload%2F%40babel%2Fplugin-transform-object-super-7.10.4.tgz"],
+ ["@babel/plugin-transform-object-super", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-object-super%2Fdownload%2F%40babel%2Fplugin-transform-object-super-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
["@babel/helper-replace-supers", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-replace-supers%2Fdownload%2F%40babel%2Fhelper-replace-supers-7.10.4.tgz"]
@@ -1519,13 +2233,26 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-object-super%2Fdownload%2F%40babel%2Fplugin-transform-object-super-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-object-super-virtual-df22b77396/0/cache/@babel-plugin-transform-object-super-npm-7.10.4-9ec43ad72e-30485dd88b.zip/node_modules/@babel/plugin-transform-object-super/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-object-super", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-object-super%2Fdownload%2F%40babel%2Fplugin-transform-object-super-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
+ ["@babel/helper-replace-supers", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-replace-supers%2Fdownload%2F%40babel%2Fhelper-replace-supers-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-parameters", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-parameters%2Fdownload%2F%40babel%2Fplugin-transform-parameters-7.10.5.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-parameters-virtual-94f262e090/0/cache/@babel-plugin-transform-parameters-npm-7.10.5-da0bd6bad6-f5da5726a2.zip/node_modules/@babel/plugin-transform-parameters/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-parameters%2Fdownload%2F%40babel%2Fplugin-transform-parameters-7.10.5.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-parameters-virtual-b725038f54/0/cache/@babel-plugin-transform-parameters-npm-7.10.5-da0bd6bad6-f5da5726a2.zip/node_modules/@babel/plugin-transform-parameters/",
"packageDependencies": [
- ["@babel/plugin-transform-parameters", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-parameters%2Fdownload%2F%40babel%2Fplugin-transform-parameters-7.10.5.tgz"],
+ ["@babel/plugin-transform-parameters", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-parameters%2Fdownload%2F%40babel%2Fplugin-transform-parameters-7.10.5.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-get-function-arity", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-get-function-arity%2Fdownload%2F%40babel%2Fhelper-get-function-arity-7.10.4.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
@@ -1534,13 +2261,26 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-parameters%2Fdownload%2F%40babel%2Fplugin-transform-parameters-7.10.5.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-parameters-virtual-955bf1755d/0/cache/@babel-plugin-transform-parameters-npm-7.10.5-da0bd6bad6-f5da5726a2.zip/node_modules/@babel/plugin-transform-parameters/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-parameters", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-parameters%2Fdownload%2F%40babel%2Fplugin-transform-parameters-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-get-function-arity", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-get-function-arity%2Fdownload%2F%40babel%2Fhelper-get-function-arity-7.10.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-property-literals", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-property-literals%2Fdownload%2F%40babel%2Fplugin-transform-property-literals-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-property-literals-virtual-7477fbdcda/0/cache/@babel-plugin-transform-property-literals-npm-7.10.4-6b2de658db-06ced62af4.zip/node_modules/@babel/plugin-transform-property-literals/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-property-literals%2Fdownload%2F%40babel%2Fplugin-transform-property-literals-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-property-literals-virtual-53dd2d39d1/0/cache/@babel-plugin-transform-property-literals-npm-7.10.4-6b2de658db-06ced62af4.zip/node_modules/@babel/plugin-transform-property-literals/",
"packageDependencies": [
- ["@babel/plugin-transform-property-literals", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-property-literals%2Fdownload%2F%40babel%2Fplugin-transform-property-literals-7.10.4.tgz"],
+ ["@babel/plugin-transform-property-literals", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-property-literals%2Fdownload%2F%40babel%2Fplugin-transform-property-literals-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1548,6 +2288,18 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-property-literals%2Fdownload%2F%40babel%2Fplugin-transform-property-literals-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-property-literals-virtual-2f5a7568cc/0/cache/@babel-plugin-transform-property-literals-npm-7.10.4-6b2de658db-06ced62af4.zip/node_modules/@babel/plugin-transform-property-literals/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-property-literals", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-property-literals%2Fdownload%2F%40babel%2Fplugin-transform-property-literals-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-react-display-name", [
@@ -1555,7 +2307,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-react-display-name-virtual-3aeae8a0d9/0/cache/@babel-plugin-transform-react-display-name-npm-7.10.4-3ca2025ce4-7a224e1163.zip/node_modules/@babel/plugin-transform-react-display-name/",
"packageDependencies": [
["@babel/plugin-transform-react-display-name", "virtual:1953e0512b6e30a17e7a43e1b60ee941d9c4f185eae0e05cdcee8720ba51d9e54edce139cdd791820e0b4691963bc37593b2c3576801c98047877349c5824ef7#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-react-display-name%2Fdownload%2F%40babel%2Fplugin-transform-react-display-name-7.10.4.tgz"],
- ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
"packagePeers": [
@@ -1569,7 +2321,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-react-jsx-virtual-b90101bd8a/0/cache/@babel-plugin-transform-react-jsx-npm-7.10.4-5305fc3b89-0fb7d136c8.zip/node_modules/@babel/plugin-transform-react-jsx/",
"packageDependencies": [
["@babel/plugin-transform-react-jsx", "virtual:1953e0512b6e30a17e7a43e1b60ee941d9c4f185eae0e05cdcee8720ba51d9e54edce139cdd791820e0b4691963bc37593b2c3576801c98047877349c5824ef7#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-react-jsx%2Fdownload%2F%40babel%2Fplugin-transform-react-jsx-7.10.4.tgz"],
- ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
["@babel/helper-builder-react-jsx", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-builder-react-jsx%2Fdownload%2F%40babel%2Fhelper-builder-react-jsx-7.10.4.tgz"],
["@babel/helper-builder-react-jsx-experimental", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-builder-react-jsx-experimental%2Fdownload%2F%40babel%2Fhelper-builder-react-jsx-experimental-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
@@ -1586,7 +2338,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-react-jsx-development-virtual-e334ae1203/0/cache/@babel-plugin-transform-react-jsx-development-npm-7.10.4-81fbc52ceb-ca014ab370.zip/node_modules/@babel/plugin-transform-react-jsx-development/",
"packageDependencies": [
["@babel/plugin-transform-react-jsx-development", "virtual:1953e0512b6e30a17e7a43e1b60ee941d9c4f185eae0e05cdcee8720ba51d9e54edce139cdd791820e0b4691963bc37593b2c3576801c98047877349c5824ef7#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-react-jsx-development%2Fdownload%2F%40babel%2Fplugin-transform-react-jsx-development-7.10.4.tgz"],
- ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
["@babel/helper-builder-react-jsx-experimental", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-builder-react-jsx-experimental%2Fdownload%2F%40babel%2Fhelper-builder-react-jsx-experimental-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
["@babel/plugin-syntax-jsx", "virtual:b90101bd8afda123e6c4ddd73f0f242aeabb99b76bf201038eabc91b1a8d0489b32520af3aa9f108ade2402c7b882bbf849a93b57b9b3340f68d73fa1729676d#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-jsx%2Fdownload%2F%40babel%2Fplugin-syntax-jsx-7.10.4.tgz"]
@@ -1602,7 +2354,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-react-jsx-self-virtual-258fde3f63/0/cache/@babel-plugin-transform-react-jsx-self-npm-7.10.4-38ff8d1d68-5447767b73.zip/node_modules/@babel/plugin-transform-react-jsx-self/",
"packageDependencies": [
["@babel/plugin-transform-react-jsx-self", "virtual:1953e0512b6e30a17e7a43e1b60ee941d9c4f185eae0e05cdcee8720ba51d9e54edce139cdd791820e0b4691963bc37593b2c3576801c98047877349c5824ef7#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-react-jsx-self%2Fdownload%2F%40babel%2Fplugin-transform-react-jsx-self-7.10.4.tgz"],
- ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
["@babel/plugin-syntax-jsx", "virtual:b90101bd8afda123e6c4ddd73f0f242aeabb99b76bf201038eabc91b1a8d0489b32520af3aa9f108ade2402c7b882bbf849a93b57b9b3340f68d73fa1729676d#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-jsx%2Fdownload%2F%40babel%2Fplugin-syntax-jsx-7.10.4.tgz"]
],
@@ -1617,7 +2369,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-react-jsx-source-virtual-c64cbbec68/0/cache/@babel-plugin-transform-react-jsx-source-npm-7.10.5-b9b878bfc7-9dc5d9bad0.zip/node_modules/@babel/plugin-transform-react-jsx-source/",
"packageDependencies": [
["@babel/plugin-transform-react-jsx-source", "virtual:1953e0512b6e30a17e7a43e1b60ee941d9c4f185eae0e05cdcee8720ba51d9e54edce139cdd791820e0b4691963bc37593b2c3576801c98047877349c5824ef7#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-react-jsx-source%2Fdownload%2F%40babel%2Fplugin-transform-react-jsx-source-7.10.5.tgz"],
- ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
["@babel/plugin-syntax-jsx", "virtual:b90101bd8afda123e6c4ddd73f0f242aeabb99b76bf201038eabc91b1a8d0489b32520af3aa9f108ade2402c7b882bbf849a93b57b9b3340f68d73fa1729676d#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-jsx%2Fdownload%2F%40babel%2Fplugin-syntax-jsx-7.10.4.tgz"]
],
@@ -1632,7 +2384,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-react-pure-annotations-virtual-615d2a4d10/0/cache/@babel-plugin-transform-react-pure-annotations-npm-7.10.4-22b0016f04-c59c44cf39.zip/node_modules/@babel/plugin-transform-react-pure-annotations/",
"packageDependencies": [
["@babel/plugin-transform-react-pure-annotations", "virtual:1953e0512b6e30a17e7a43e1b60ee941d9c4f185eae0e05cdcee8720ba51d9e54edce139cdd791820e0b4691963bc37593b2c3576801c98047877349c5824ef7#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-react-pure-annotations%2Fdownload%2F%40babel%2Fplugin-transform-react-pure-annotations-7.10.4.tgz"],
- ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
["@babel/helper-annotate-as-pure", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-annotate-as-pure%2Fdownload%2F%40babel%2Fhelper-annotate-as-pure-7.10.4.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1643,10 +2395,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/plugin-transform-regenerator", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-regenerator%2Fdownload%2F%40babel%2Fplugin-transform-regenerator-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-regenerator-virtual-6d9259afec/0/cache/@babel-plugin-transform-regenerator-npm-7.10.4-3592e1fe8d-932b35c5ed.zip/node_modules/@babel/plugin-transform-regenerator/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-regenerator%2Fdownload%2F%40babel%2Fplugin-transform-regenerator-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-regenerator-virtual-b13c77d07b/0/cache/@babel-plugin-transform-regenerator-npm-7.10.4-3592e1fe8d-932b35c5ed.zip/node_modules/@babel/plugin-transform-regenerator/",
"packageDependencies": [
- ["@babel/plugin-transform-regenerator", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-regenerator%2Fdownload%2F%40babel%2Fplugin-transform-regenerator-7.10.4.tgz"],
+ ["@babel/plugin-transform-regenerator", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-regenerator%2Fdownload%2F%40babel%2Fplugin-transform-regenerator-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["regenerator-transform", "npm:0.14.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-transform%2Fdownload%2Fregenerator-transform-0.14.5.tgz"]
],
@@ -1654,13 +2406,25 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-regenerator%2Fdownload%2F%40babel%2Fplugin-transform-regenerator-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-regenerator-virtual-137fc1864b/0/cache/@babel-plugin-transform-regenerator-npm-7.10.4-3592e1fe8d-932b35c5ed.zip/node_modules/@babel/plugin-transform-regenerator/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-regenerator", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-regenerator%2Fdownload%2F%40babel%2Fplugin-transform-regenerator-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["regenerator-transform", "npm:0.14.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-transform%2Fdownload%2Fregenerator-transform-0.14.5.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-reserved-words", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-reserved-words%2Fdownload%2F%40babel%2Fplugin-transform-reserved-words-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-reserved-words-virtual-5640e5869c/0/cache/@babel-plugin-transform-reserved-words-npm-7.10.4-c2a9152983-457433e66e.zip/node_modules/@babel/plugin-transform-reserved-words/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-reserved-words%2Fdownload%2F%40babel%2Fplugin-transform-reserved-words-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-reserved-words-virtual-4ced5f1392/0/cache/@babel-plugin-transform-reserved-words-npm-7.10.4-c2a9152983-457433e66e.zip/node_modules/@babel/plugin-transform-reserved-words/",
"packageDependencies": [
- ["@babel/plugin-transform-reserved-words", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-reserved-words%2Fdownload%2F%40babel%2Fplugin-transform-reserved-words-7.10.4.tgz"],
+ ["@babel/plugin-transform-reserved-words", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-reserved-words%2Fdownload%2F%40babel%2Fplugin-transform-reserved-words-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1668,13 +2432,25 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-reserved-words%2Fdownload%2F%40babel%2Fplugin-transform-reserved-words-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-reserved-words-virtual-44a999d730/0/cache/@babel-plugin-transform-reserved-words-npm-7.10.4-c2a9152983-457433e66e.zip/node_modules/@babel/plugin-transform-reserved-words/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-reserved-words", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-reserved-words%2Fdownload%2F%40babel%2Fplugin-transform-reserved-words-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-shorthand-properties", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-shorthand-properties%2Fdownload%2F%40babel%2Fplugin-transform-shorthand-properties-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-shorthand-properties-virtual-01ea33fdb7/0/cache/@babel-plugin-transform-shorthand-properties-npm-7.10.4-9adc4ae66c-91ba5aa099.zip/node_modules/@babel/plugin-transform-shorthand-properties/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-shorthand-properties%2Fdownload%2F%40babel%2Fplugin-transform-shorthand-properties-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-shorthand-properties-virtual-4804b5fa52/0/cache/@babel-plugin-transform-shorthand-properties-npm-7.10.4-9adc4ae66c-91ba5aa099.zip/node_modules/@babel/plugin-transform-shorthand-properties/",
"packageDependencies": [
- ["@babel/plugin-transform-shorthand-properties", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-shorthand-properties%2Fdownload%2F%40babel%2Fplugin-transform-shorthand-properties-7.10.4.tgz"],
+ ["@babel/plugin-transform-shorthand-properties", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-shorthand-properties%2Fdownload%2F%40babel%2Fplugin-transform-shorthand-properties-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1682,13 +2458,25 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-shorthand-properties%2Fdownload%2F%40babel%2Fplugin-transform-shorthand-properties-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-shorthand-properties-virtual-d60ee07e47/0/cache/@babel-plugin-transform-shorthand-properties-npm-7.10.4-9adc4ae66c-91ba5aa099.zip/node_modules/@babel/plugin-transform-shorthand-properties/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-shorthand-properties", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-shorthand-properties%2Fdownload%2F%40babel%2Fplugin-transform-shorthand-properties-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-spread", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-spread%2Fdownload%2F%40babel%2Fplugin-transform-spread-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-spread-virtual-eb8c90c5db/0/cache/@babel-plugin-transform-spread-npm-7.10.4-04602f43c6-67ac6ffa64.zip/node_modules/@babel/plugin-transform-spread/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-spread%2Fdownload%2F%40babel%2Fplugin-transform-spread-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-spread-virtual-2a6f7712af/0/cache/@babel-plugin-transform-spread-npm-7.10.4-04602f43c6-67ac6ffa64.zip/node_modules/@babel/plugin-transform-spread/",
"packageDependencies": [
- ["@babel/plugin-transform-spread", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-spread%2Fdownload%2F%40babel%2Fplugin-transform-spread-7.10.4.tgz"],
+ ["@babel/plugin-transform-spread", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-spread%2Fdownload%2F%40babel%2Fplugin-transform-spread-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1696,13 +2484,26 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-spread%2Fdownload%2F%40babel%2Fplugin-transform-spread-7.11.0.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-spread-virtual-ab40c88c6d/0/cache/@babel-plugin-transform-spread-npm-7.11.0-d2425d4411-b10b0608d9.zip/node_modules/@babel/plugin-transform-spread/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-spread", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-spread%2Fdownload%2F%40babel%2Fplugin-transform-spread-7.11.0.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
+ ["@babel/helper-skip-transparent-expression-wrappers", "npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-skip-transparent-expression-wrappers%2Fdownload%2F%40babel%2Fhelper-skip-transparent-expression-wrappers-7.11.0.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-sticky-regex", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-sticky-regex%2Fdownload%2F%40babel%2Fplugin-transform-sticky-regex-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-sticky-regex-virtual-eff096249e/0/cache/@babel-plugin-transform-sticky-regex-npm-7.10.4-18c5345a64-56eed04e48.zip/node_modules/@babel/plugin-transform-sticky-regex/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-sticky-regex%2Fdownload%2F%40babel%2Fplugin-transform-sticky-regex-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-sticky-regex-virtual-1553f8c2cf/0/cache/@babel-plugin-transform-sticky-regex-npm-7.10.4-18c5345a64-56eed04e48.zip/node_modules/@babel/plugin-transform-sticky-regex/",
"packageDependencies": [
- ["@babel/plugin-transform-sticky-regex", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-sticky-regex%2Fdownload%2F%40babel%2Fplugin-transform-sticky-regex-7.10.4.tgz"],
+ ["@babel/plugin-transform-sticky-regex", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-sticky-regex%2Fdownload%2F%40babel%2Fplugin-transform-sticky-regex-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
["@babel/helper-regex", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-regex%2Fdownload%2F%40babel%2Fhelper-regex-7.10.5.tgz"]
@@ -1711,13 +2512,26 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-sticky-regex%2Fdownload%2F%40babel%2Fplugin-transform-sticky-regex-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-sticky-regex-virtual-fe458784b3/0/cache/@babel-plugin-transform-sticky-regex-npm-7.10.4-18c5345a64-56eed04e48.zip/node_modules/@babel/plugin-transform-sticky-regex/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-sticky-regex", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-sticky-regex%2Fdownload%2F%40babel%2Fplugin-transform-sticky-regex-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
+ ["@babel/helper-regex", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-regex%2Fdownload%2F%40babel%2Fhelper-regex-7.10.5.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-template-literals", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-template-literals%2Fdownload%2F%40babel%2Fplugin-transform-template-literals-7.10.5.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-template-literals-virtual-5bb3828347/0/cache/@babel-plugin-transform-template-literals-npm-7.10.5-c2c3a22f4a-bd5e87e407.zip/node_modules/@babel/plugin-transform-template-literals/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-template-literals%2Fdownload%2F%40babel%2Fplugin-transform-template-literals-7.10.5.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-template-literals-virtual-d9c731519d/0/cache/@babel-plugin-transform-template-literals-npm-7.10.5-c2c3a22f4a-bd5e87e407.zip/node_modules/@babel/plugin-transform-template-literals/",
"packageDependencies": [
- ["@babel/plugin-transform-template-literals", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-template-literals%2Fdownload%2F%40babel%2Fplugin-transform-template-literals-7.10.5.tgz"],
+ ["@babel/plugin-transform-template-literals", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-template-literals%2Fdownload%2F%40babel%2Fplugin-transform-template-literals-7.10.5.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-annotate-as-pure", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-annotate-as-pure%2Fdownload%2F%40babel%2Fhelper-annotate-as-pure-7.10.4.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
@@ -1726,13 +2540,26 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-template-literals%2Fdownload%2F%40babel%2Fplugin-transform-template-literals-7.10.5.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-template-literals-virtual-eb7b905c72/0/cache/@babel-plugin-transform-template-literals-npm-7.10.5-c2c3a22f4a-bd5e87e407.zip/node_modules/@babel/plugin-transform-template-literals/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-template-literals", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-template-literals%2Fdownload%2F%40babel%2Fplugin-transform-template-literals-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-annotate-as-pure", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-annotate-as-pure%2Fdownload%2F%40babel%2Fhelper-annotate-as-pure-7.10.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-typeof-symbol", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-typeof-symbol%2Fdownload%2F%40babel%2Fplugin-transform-typeof-symbol-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-typeof-symbol-virtual-41251d0d79/0/cache/@babel-plugin-transform-typeof-symbol-npm-7.10.4-d111400431-13f3e75372.zip/node_modules/@babel/plugin-transform-typeof-symbol/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-typeof-symbol%2Fdownload%2F%40babel%2Fplugin-transform-typeof-symbol-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-typeof-symbol-virtual-38c436135a/0/cache/@babel-plugin-transform-typeof-symbol-npm-7.10.4-d111400431-13f3e75372.zip/node_modules/@babel/plugin-transform-typeof-symbol/",
"packageDependencies": [
- ["@babel/plugin-transform-typeof-symbol", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-typeof-symbol%2Fdownload%2F%40babel%2Fplugin-transform-typeof-symbol-7.10.4.tgz"],
+ ["@babel/plugin-transform-typeof-symbol", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-typeof-symbol%2Fdownload%2F%40babel%2Fplugin-transform-typeof-symbol-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1740,6 +2567,18 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-typeof-symbol%2Fdownload%2F%40babel%2Fplugin-transform-typeof-symbol-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-typeof-symbol-virtual-8f85adefbc/0/cache/@babel-plugin-transform-typeof-symbol-npm-7.10.4-d111400431-13f3e75372.zip/node_modules/@babel/plugin-transform-typeof-symbol/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-typeof-symbol", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-typeof-symbol%2Fdownload%2F%40babel%2Fplugin-transform-typeof-symbol-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-typescript", [
@@ -1747,7 +2586,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-typescript-virtual-b2bda09167/0/cache/@babel-plugin-transform-typescript-npm-7.10.5-476929e915-fed2784756.zip/node_modules/@babel/plugin-transform-typescript/",
"packageDependencies": [
["@babel/plugin-transform-typescript", "virtual:6fec19edd8abb0c228b7761c4f066e29e1dcdd569dfaabffcb8721701d685f707551e64dbfb2a8a84b999f8a6a4a28c0954962f30bc5802165d47de83e24991f#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-typescript%2Fdownload%2F%40babel%2Fplugin-transform-typescript-7.10.5.tgz"],
- ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
["@babel/helper-create-class-features-plugin", "virtual:75c4dd0d2cd4b70bccb9932d6191569166cd0d5b906f73a0fa2e9f1a8aa2083703807d3c72e28f347cb193c2d3d3c614c438b60e7caa972fcd47c4edfe631ffd#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-class-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-class-features-plugin-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
["@babel/plugin-syntax-typescript", "virtual:b2bda0916789a79a30759540ac5b83df187fa32f9233c09c0178a4a113d8a478f18f47cf1cad69d5fa966f1e94861b3c726ec222eb41f27ac6ee65b2acfa9c97#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-typescript%2Fdownload%2F%40babel%2Fplugin-syntax-typescript-7.10.4.tgz"]
@@ -1759,10 +2598,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/plugin-transform-unicode-escapes", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-escapes%2Fdownload%2F%40babel%2Fplugin-transform-unicode-escapes-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-unicode-escapes-virtual-1309dbbe5f/0/cache/@babel-plugin-transform-unicode-escapes-npm-7.10.4-e9c8ca4a01-c7467a508f.zip/node_modules/@babel/plugin-transform-unicode-escapes/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-escapes%2Fdownload%2F%40babel%2Fplugin-transform-unicode-escapes-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-unicode-escapes-virtual-3c7afc373f/0/cache/@babel-plugin-transform-unicode-escapes-npm-7.10.4-e9c8ca4a01-c7467a508f.zip/node_modules/@babel/plugin-transform-unicode-escapes/",
"packageDependencies": [
- ["@babel/plugin-transform-unicode-escapes", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-escapes%2Fdownload%2F%40babel%2Fplugin-transform-unicode-escapes-7.10.4.tgz"],
+ ["@babel/plugin-transform-unicode-escapes", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-escapes%2Fdownload%2F%40babel%2Fplugin-transform-unicode-escapes-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
@@ -1770,15 +2609,40 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "@babel/core"
],
"linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-escapes%2Fdownload%2F%40babel%2Fplugin-transform-unicode-escapes-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-unicode-escapes-virtual-19f24be85f/0/cache/@babel-plugin-transform-unicode-escapes-npm-7.10.4-e9c8ca4a01-c7467a508f.zip/node_modules/@babel/plugin-transform-unicode-escapes/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-unicode-escapes", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-escapes%2Fdownload%2F%40babel%2Fplugin-transform-unicode-escapes-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/plugin-transform-unicode-regex", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-regex%2Fdownload%2F%40babel%2Fplugin-transform-unicode-regex-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-unicode-regex-virtual-db716439bc/0/cache/@babel-plugin-transform-unicode-regex-npm-7.10.4-9982080bf3-2e0762e7fa.zip/node_modules/@babel/plugin-transform-unicode-regex/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-regex%2Fdownload%2F%40babel%2Fplugin-transform-unicode-regex-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-unicode-regex-virtual-53f7243893/0/cache/@babel-plugin-transform-unicode-regex-npm-7.10.4-9982080bf3-2e0762e7fa.zip/node_modules/@babel/plugin-transform-unicode-regex/",
"packageDependencies": [
- ["@babel/plugin-transform-unicode-regex", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-regex%2Fdownload%2F%40babel%2Fplugin-transform-unicode-regex-7.10.4.tgz"],
+ ["@babel/plugin-transform-unicode-regex", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-regex%2Fdownload%2F%40babel%2Fplugin-transform-unicode-regex-7.10.4.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
- ["@babel/helper-create-regexp-features-plugin", "virtual:4e95dff1e4d799ff1ad5b1d72fb9e856f303a7db3c862cc93ca2390c538394d4a4a141e0cac4effa2a8dba9bf2e598221f9095418d8d91d03b81ae16281a991b#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-regexp-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-regexp-features-plugin-7.10.4.tgz"],
+ ["@babel/helper-create-regexp-features-plugin", "virtual:603d46702a42ce5c1028458dccd33e2fb1f5c8827f04e28a6705e7321c377b2ceab089d1924f8dc9a3517025ec0466db221bd611c0c591fb724085dc966cc3fc#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-regexp-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-regexp-features-plugin-7.10.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-regex%2Fdownload%2F%40babel%2Fplugin-transform-unicode-regex-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-plugin-transform-unicode-regex-virtual-e785834074/0/cache/@babel-plugin-transform-unicode-regex-npm-7.10.4-9982080bf3-2e0762e7fa.zip/node_modules/@babel/plugin-transform-unicode-regex/",
+ "packageDependencies": [
+ ["@babel/plugin-transform-unicode-regex", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-regex%2Fdownload%2F%40babel%2Fplugin-transform-unicode-regex-7.10.4.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-create-regexp-features-plugin", "virtual:cb2dd087c703ec7307b541f992f3886d88eb72680bfa1ed88da28ff8b65d87d95e29d9e038cf20b422f8c09e4062de4c8890d7150f32e96e4d9866ffa2fdb838#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-regexp-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-regexp-features-plugin-7.10.4.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"]
],
"packagePeers": [
@@ -1788,70 +2652,149 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/preset-env", [
- ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-env%2Fdownload%2F%40babel%2Fpreset-env-7.10.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-preset-env-virtual-5656a0f4b5/0/cache/@babel-preset-env-npm-7.10.4-2e0b9e093e-c13fe3c2c4.zip/node_modules/@babel/preset-env/",
+ ["virtual:3e7d201acb70f99b496fd22382494a547adba7ced83157fcf203a35a809a1a86e9fcdadc98baf8c5919858aa7474058982ca7332a042017e29b0e7f90348de11#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-env%2Fdownload%2F%40babel%2Fpreset-env-7.10.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-preset-env-virtual-068c8b8eda/0/cache/@babel-preset-env-npm-7.10.4-2e0b9e093e-c13fe3c2c4.zip/node_modules/@babel/preset-env/",
"packageDependencies": [
- ["@babel/preset-env", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-env%2Fdownload%2F%40babel%2Fpreset-env-7.10.4.tgz"],
+ ["@babel/preset-env", "virtual:3e7d201acb70f99b496fd22382494a547adba7ced83157fcf203a35a809a1a86e9fcdadc98baf8c5919858aa7474058982ca7332a042017e29b0e7f90348de11#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-env%2Fdownload%2F%40babel%2Fpreset-env-7.10.4.tgz"],
["@babel/compat-data", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcompat-data%2Fdownload%2F%40babel%2Fcompat-data-7.10.5.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
- ["@babel/helper-compilation-targets", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-compilation-targets%2Fdownload%2F%40babel%2Fhelper-compilation-targets-7.10.4.tgz"],
+ ["@babel/helper-compilation-targets", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-compilation-targets%2Fdownload%2F%40babel%2Fhelper-compilation-targets-7.10.4.tgz"],
["@babel/helper-module-imports", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-imports%2Fdownload%2F%40babel%2Fhelper-module-imports-7.10.4.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
- ["@babel/plugin-proposal-async-generator-functions", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-async-generator-functions%2Fdownload%2F%40babel%2Fplugin-proposal-async-generator-functions-7.10.5.tgz"],
+ ["@babel/plugin-proposal-async-generator-functions", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-async-generator-functions%2Fdownload%2F%40babel%2Fplugin-proposal-async-generator-functions-7.10.5.tgz"],
+ ["@babel/plugin-proposal-class-properties", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-class-properties%2Fdownload%2F%40babel%2Fplugin-proposal-class-properties-7.10.4.tgz"],
+ ["@babel/plugin-proposal-dynamic-import", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-dynamic-import%2Fdownload%2F%40babel%2Fplugin-proposal-dynamic-import-7.10.4.tgz"],
+ ["@babel/plugin-proposal-json-strings", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-json-strings%2Fdownload%2F%40babel%2Fplugin-proposal-json-strings-7.10.4.tgz"],
+ ["@babel/plugin-proposal-nullish-coalescing-operator", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator%2Fdownload%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator-7.10.4.tgz"],
+ ["@babel/plugin-proposal-numeric-separator", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-numeric-separator%2Fdownload%2F%40babel%2Fplugin-proposal-numeric-separator-7.10.4.tgz"],
+ ["@babel/plugin-proposal-object-rest-spread", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-proposal-object-rest-spread-7.10.4.tgz"],
+ ["@babel/plugin-proposal-optional-catch-binding", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-proposal-optional-catch-binding-7.10.4.tgz"],
+ ["@babel/plugin-proposal-optional-chaining", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-chaining%2Fdownload%2F%40babel%2Fplugin-proposal-optional-chaining-7.10.4.tgz"],
+ ["@babel/plugin-proposal-private-methods", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-private-methods%2Fdownload%2F%40babel%2Fplugin-proposal-private-methods-7.10.4.tgz"],
+ ["@babel/plugin-proposal-unicode-property-regex", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-unicode-property-regex%2Fdownload%2F%40babel%2Fplugin-proposal-unicode-property-regex-7.10.4.tgz"],
+ ["@babel/plugin-syntax-async-generators", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-async-generators%2Fdownload%2F%40babel%2Fplugin-syntax-async-generators-7.8.4.tgz"],
+ ["@babel/plugin-syntax-class-properties", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-class-properties%2Fdownload%2F%40babel%2Fplugin-syntax-class-properties-7.10.4.tgz"],
+ ["@babel/plugin-syntax-dynamic-import", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-dynamic-import%2Fdownload%2F%40babel%2Fplugin-syntax-dynamic-import-7.8.3.tgz"],
+ ["@babel/plugin-syntax-json-strings", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-json-strings%2Fdownload%2F%40babel%2Fplugin-syntax-json-strings-7.8.3.tgz"],
+ ["@babel/plugin-syntax-nullish-coalescing-operator", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-nullish-coalescing-operator%2Fdownload%2F%40babel%2Fplugin-syntax-nullish-coalescing-operator-7.8.3.tgz"],
+ ["@babel/plugin-syntax-numeric-separator", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-numeric-separator%2Fdownload%2F%40babel%2Fplugin-syntax-numeric-separator-7.10.4.tgz"],
+ ["@babel/plugin-syntax-object-rest-spread", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-syntax-object-rest-spread-7.8.3.tgz"],
+ ["@babel/plugin-syntax-optional-catch-binding", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-syntax-optional-catch-binding-7.8.3.tgz"],
+ ["@babel/plugin-syntax-optional-chaining", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-chaining%2Fdownload%2F%40babel%2Fplugin-syntax-optional-chaining-7.8.3.tgz"],
+ ["@babel/plugin-syntax-top-level-await", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-top-level-await%2Fdownload%2F%40babel%2Fplugin-syntax-top-level-await-7.10.4.tgz"],
+ ["@babel/plugin-transform-arrow-functions", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-arrow-functions%2Fdownload%2F%40babel%2Fplugin-transform-arrow-functions-7.10.4.tgz"],
+ ["@babel/plugin-transform-async-to-generator", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-async-to-generator%2Fdownload%2F%40babel%2Fplugin-transform-async-to-generator-7.10.4.tgz"],
+ ["@babel/plugin-transform-block-scoped-functions", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoped-functions%2Fdownload%2F%40babel%2Fplugin-transform-block-scoped-functions-7.10.4.tgz"],
+ ["@babel/plugin-transform-block-scoping", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoping%2Fdownload%2F%40babel%2Fplugin-transform-block-scoping-7.10.5.tgz"],
+ ["@babel/plugin-transform-classes", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-classes%2Fdownload%2F%40babel%2Fplugin-transform-classes-7.10.4.tgz"],
+ ["@babel/plugin-transform-computed-properties", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-computed-properties%2Fdownload%2F%40babel%2Fplugin-transform-computed-properties-7.10.4.tgz"],
+ ["@babel/plugin-transform-destructuring", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-destructuring%2Fdownload%2F%40babel%2Fplugin-transform-destructuring-7.10.4.tgz"],
+ ["@babel/plugin-transform-dotall-regex", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-dotall-regex%2Fdownload%2F%40babel%2Fplugin-transform-dotall-regex-7.10.4.tgz"],
+ ["@babel/plugin-transform-duplicate-keys", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-duplicate-keys%2Fdownload%2F%40babel%2Fplugin-transform-duplicate-keys-7.10.4.tgz"],
+ ["@babel/plugin-transform-exponentiation-operator", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-exponentiation-operator%2Fdownload%2F%40babel%2Fplugin-transform-exponentiation-operator-7.10.4.tgz"],
+ ["@babel/plugin-transform-for-of", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-for-of%2Fdownload%2F%40babel%2Fplugin-transform-for-of-7.10.4.tgz"],
+ ["@babel/plugin-transform-function-name", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-function-name%2Fdownload%2F%40babel%2Fplugin-transform-function-name-7.10.4.tgz"],
+ ["@babel/plugin-transform-literals", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-literals%2Fdownload%2F%40babel%2Fplugin-transform-literals-7.10.4.tgz"],
+ ["@babel/plugin-transform-member-expression-literals", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-member-expression-literals%2Fdownload%2F%40babel%2Fplugin-transform-member-expression-literals-7.10.4.tgz"],
+ ["@babel/plugin-transform-modules-amd", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-amd%2Fdownload%2F%40babel%2Fplugin-transform-modules-amd-7.10.5.tgz"],
+ ["@babel/plugin-transform-modules-commonjs", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-commonjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-commonjs-7.10.4.tgz"],
+ ["@babel/plugin-transform-modules-systemjs", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-systemjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-systemjs-7.10.5.tgz"],
+ ["@babel/plugin-transform-modules-umd", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-umd%2Fdownload%2F%40babel%2Fplugin-transform-modules-umd-7.10.4.tgz"],
+ ["@babel/plugin-transform-named-capturing-groups-regex", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-named-capturing-groups-regex%2Fdownload%2F%40babel%2Fplugin-transform-named-capturing-groups-regex-7.10.4.tgz"],
+ ["@babel/plugin-transform-new-target", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-new-target%2Fdownload%2F%40babel%2Fplugin-transform-new-target-7.10.4.tgz"],
+ ["@babel/plugin-transform-object-super", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-object-super%2Fdownload%2F%40babel%2Fplugin-transform-object-super-7.10.4.tgz"],
+ ["@babel/plugin-transform-parameters", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-parameters%2Fdownload%2F%40babel%2Fplugin-transform-parameters-7.10.5.tgz"],
+ ["@babel/plugin-transform-property-literals", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-property-literals%2Fdownload%2F%40babel%2Fplugin-transform-property-literals-7.10.4.tgz"],
+ ["@babel/plugin-transform-regenerator", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-regenerator%2Fdownload%2F%40babel%2Fplugin-transform-regenerator-7.10.4.tgz"],
+ ["@babel/plugin-transform-reserved-words", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-reserved-words%2Fdownload%2F%40babel%2Fplugin-transform-reserved-words-7.10.4.tgz"],
+ ["@babel/plugin-transform-shorthand-properties", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-shorthand-properties%2Fdownload%2F%40babel%2Fplugin-transform-shorthand-properties-7.10.4.tgz"],
+ ["@babel/plugin-transform-spread", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-spread%2Fdownload%2F%40babel%2Fplugin-transform-spread-7.10.4.tgz"],
+ ["@babel/plugin-transform-sticky-regex", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-sticky-regex%2Fdownload%2F%40babel%2Fplugin-transform-sticky-regex-7.10.4.tgz"],
+ ["@babel/plugin-transform-template-literals", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-template-literals%2Fdownload%2F%40babel%2Fplugin-transform-template-literals-7.10.5.tgz"],
+ ["@babel/plugin-transform-typeof-symbol", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-typeof-symbol%2Fdownload%2F%40babel%2Fplugin-transform-typeof-symbol-7.10.4.tgz"],
+ ["@babel/plugin-transform-unicode-escapes", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-escapes%2Fdownload%2F%40babel%2Fplugin-transform-unicode-escapes-7.10.4.tgz"],
+ ["@babel/plugin-transform-unicode-regex", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-regex%2Fdownload%2F%40babel%2Fplugin-transform-unicode-regex-7.10.4.tgz"],
+ ["@babel/preset-modules", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:0.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-modules%2Fdownload%2F%40babel%2Fpreset-modules-0.1.3.tgz"],
+ ["@babel/types", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.10.5.tgz"],
+ ["browserslist", "npm:4.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbrowserslist%2Fdownload%2Fbrowserslist-4.13.0.tgz"],
+ ["core-js-compat", "npm:3.6.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js-compat%2Fdownload%2Fcore-js-compat-3.6.5.tgz"],
+ ["invariant", "npm:2.2.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Finvariant%2Fdownload%2Finvariant-2.2.4.tgz"],
+ ["levenary", "npm:1.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flevenary%2Fdownload%2Flevenary-1.1.1.tgz"],
+ ["semver", "npm:5.7.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }],
+ ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-env%2Fdownload%2F%40babel%2Fpreset-env-7.11.0.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-preset-env-virtual-fe72b7f1f8/0/cache/@babel-preset-env-npm-7.11.0-64cf59fcda-5ce0e1d188.zip/node_modules/@babel/preset-env/",
+ "packageDependencies": [
+ ["@babel/preset-env", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-env%2Fdownload%2F%40babel%2Fpreset-env-7.11.0.tgz"],
+ ["@babel/compat-data", "npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcompat-data%2Fdownload%2F%40babel%2Fcompat-data-7.11.0.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-compilation-targets", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-compilation-targets%2Fdownload%2F%40babel%2Fhelper-compilation-targets-7.10.4.tgz"],
+ ["@babel/helper-module-imports", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-imports%2Fdownload%2F%40babel%2Fhelper-module-imports-7.10.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
+ ["@babel/plugin-proposal-async-generator-functions", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-async-generator-functions%2Fdownload%2F%40babel%2Fplugin-proposal-async-generator-functions-7.10.5.tgz"],
["@babel/plugin-proposal-class-properties", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-class-properties%2Fdownload%2F%40babel%2Fplugin-proposal-class-properties-7.10.4.tgz"],
- ["@babel/plugin-proposal-dynamic-import", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-dynamic-import%2Fdownload%2F%40babel%2Fplugin-proposal-dynamic-import-7.10.4.tgz"],
- ["@babel/plugin-proposal-json-strings", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-json-strings%2Fdownload%2F%40babel%2Fplugin-proposal-json-strings-7.10.4.tgz"],
+ ["@babel/plugin-proposal-dynamic-import", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-dynamic-import%2Fdownload%2F%40babel%2Fplugin-proposal-dynamic-import-7.10.4.tgz"],
+ ["@babel/plugin-proposal-export-namespace-from", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-export-namespace-from%2Fdownload%2F%40babel%2Fplugin-proposal-export-namespace-from-7.10.4.tgz"],
+ ["@babel/plugin-proposal-json-strings", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-json-strings%2Fdownload%2F%40babel%2Fplugin-proposal-json-strings-7.10.4.tgz"],
+ ["@babel/plugin-proposal-logical-assignment-operators", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-logical-assignment-operators%2Fdownload%2F%40babel%2Fplugin-proposal-logical-assignment-operators-7.11.0.tgz"],
["@babel/plugin-proposal-nullish-coalescing-operator", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator%2Fdownload%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator-7.10.4.tgz"],
- ["@babel/plugin-proposal-numeric-separator", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-numeric-separator%2Fdownload%2F%40babel%2Fplugin-proposal-numeric-separator-7.10.4.tgz"],
- ["@babel/plugin-proposal-object-rest-spread", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-proposal-object-rest-spread-7.10.4.tgz"],
- ["@babel/plugin-proposal-optional-catch-binding", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-proposal-optional-catch-binding-7.10.4.tgz"],
- ["@babel/plugin-proposal-optional-chaining", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-chaining%2Fdownload%2F%40babel%2Fplugin-proposal-optional-chaining-7.10.4.tgz"],
- ["@babel/plugin-proposal-private-methods", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-private-methods%2Fdownload%2F%40babel%2Fplugin-proposal-private-methods-7.10.4.tgz"],
- ["@babel/plugin-proposal-unicode-property-regex", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-unicode-property-regex%2Fdownload%2F%40babel%2Fplugin-proposal-unicode-property-regex-7.10.4.tgz"],
- ["@babel/plugin-syntax-async-generators", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.8.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-async-generators%2Fdownload%2F%40babel%2Fplugin-syntax-async-generators-7.8.4.tgz"],
- ["@babel/plugin-syntax-class-properties", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-class-properties%2Fdownload%2F%40babel%2Fplugin-syntax-class-properties-7.10.4.tgz"],
+ ["@babel/plugin-proposal-numeric-separator", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-numeric-separator%2Fdownload%2F%40babel%2Fplugin-proposal-numeric-separator-7.10.4.tgz"],
+ ["@babel/plugin-proposal-object-rest-spread", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-proposal-object-rest-spread-7.11.0.tgz"],
+ ["@babel/plugin-proposal-optional-catch-binding", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-proposal-optional-catch-binding-7.10.4.tgz"],
+ ["@babel/plugin-proposal-optional-chaining", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-chaining%2Fdownload%2F%40babel%2Fplugin-proposal-optional-chaining-7.11.0.tgz"],
+ ["@babel/plugin-proposal-private-methods", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-private-methods%2Fdownload%2F%40babel%2Fplugin-proposal-private-methods-7.10.4.tgz"],
+ ["@babel/plugin-proposal-unicode-property-regex", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-unicode-property-regex%2Fdownload%2F%40babel%2Fplugin-proposal-unicode-property-regex-7.10.4.tgz"],
+ ["@babel/plugin-syntax-async-generators", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.8.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-async-generators%2Fdownload%2F%40babel%2Fplugin-syntax-async-generators-7.8.4.tgz"],
+ ["@babel/plugin-syntax-class-properties", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-class-properties%2Fdownload%2F%40babel%2Fplugin-syntax-class-properties-7.10.4.tgz"],
["@babel/plugin-syntax-dynamic-import", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-dynamic-import%2Fdownload%2F%40babel%2Fplugin-syntax-dynamic-import-7.8.3.tgz"],
- ["@babel/plugin-syntax-json-strings", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-json-strings%2Fdownload%2F%40babel%2Fplugin-syntax-json-strings-7.8.3.tgz"],
+ ["@babel/plugin-syntax-export-namespace-from", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-export-namespace-from%2Fdownload%2F%40babel%2Fplugin-syntax-export-namespace-from-7.8.3.tgz"],
+ ["@babel/plugin-syntax-json-strings", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-json-strings%2Fdownload%2F%40babel%2Fplugin-syntax-json-strings-7.8.3.tgz"],
+ ["@babel/plugin-syntax-logical-assignment-operators", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-logical-assignment-operators%2Fdownload%2F%40babel%2Fplugin-syntax-logical-assignment-operators-7.10.4.tgz"],
["@babel/plugin-syntax-nullish-coalescing-operator", "virtual:1aafd484e7c5739d9135bb3b82d8e863096fd061b8289a1e58fdc6707690db2c22912ae5275c7ec0ea6fb457d9aeba6d3d0f5d2e62cbebde76831d72dbc6b575#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-nullish-coalescing-operator%2Fdownload%2F%40babel%2Fplugin-syntax-nullish-coalescing-operator-7.8.3.tgz"],
- ["@babel/plugin-syntax-numeric-separator", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-numeric-separator%2Fdownload%2F%40babel%2Fplugin-syntax-numeric-separator-7.10.4.tgz"],
- ["@babel/plugin-syntax-object-rest-spread", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-syntax-object-rest-spread-7.8.3.tgz"],
- ["@babel/plugin-syntax-optional-catch-binding", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-syntax-optional-catch-binding-7.8.3.tgz"],
- ["@babel/plugin-syntax-optional-chaining", "virtual:303da2bcf7cb54ecbdab5aadd757aceee31fcf731c58ada79b826235fd05987c4fd49cd36aa85ed9812896b79a14b330d14b59a9bb31b7a4f8a671b30938e476#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-chaining%2Fdownload%2F%40babel%2Fplugin-syntax-optional-chaining-7.8.3.tgz"],
- ["@babel/plugin-syntax-top-level-await", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-top-level-await%2Fdownload%2F%40babel%2Fplugin-syntax-top-level-await-7.10.4.tgz"],
- ["@babel/plugin-transform-arrow-functions", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-arrow-functions%2Fdownload%2F%40babel%2Fplugin-transform-arrow-functions-7.10.4.tgz"],
- ["@babel/plugin-transform-async-to-generator", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-async-to-generator%2Fdownload%2F%40babel%2Fplugin-transform-async-to-generator-7.10.4.tgz"],
- ["@babel/plugin-transform-block-scoped-functions", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoped-functions%2Fdownload%2F%40babel%2Fplugin-transform-block-scoped-functions-7.10.4.tgz"],
- ["@babel/plugin-transform-block-scoping", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoping%2Fdownload%2F%40babel%2Fplugin-transform-block-scoping-7.10.5.tgz"],
- ["@babel/plugin-transform-classes", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-classes%2Fdownload%2F%40babel%2Fplugin-transform-classes-7.10.4.tgz"],
- ["@babel/plugin-transform-computed-properties", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-computed-properties%2Fdownload%2F%40babel%2Fplugin-transform-computed-properties-7.10.4.tgz"],
- ["@babel/plugin-transform-destructuring", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-destructuring%2Fdownload%2F%40babel%2Fplugin-transform-destructuring-7.10.4.tgz"],
- ["@babel/plugin-transform-dotall-regex", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-dotall-regex%2Fdownload%2F%40babel%2Fplugin-transform-dotall-regex-7.10.4.tgz"],
- ["@babel/plugin-transform-duplicate-keys", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-duplicate-keys%2Fdownload%2F%40babel%2Fplugin-transform-duplicate-keys-7.10.4.tgz"],
- ["@babel/plugin-transform-exponentiation-operator", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-exponentiation-operator%2Fdownload%2F%40babel%2Fplugin-transform-exponentiation-operator-7.10.4.tgz"],
- ["@babel/plugin-transform-for-of", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-for-of%2Fdownload%2F%40babel%2Fplugin-transform-for-of-7.10.4.tgz"],
- ["@babel/plugin-transform-function-name", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-function-name%2Fdownload%2F%40babel%2Fplugin-transform-function-name-7.10.4.tgz"],
- ["@babel/plugin-transform-literals", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-literals%2Fdownload%2F%40babel%2Fplugin-transform-literals-7.10.4.tgz"],
- ["@babel/plugin-transform-member-expression-literals", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-member-expression-literals%2Fdownload%2F%40babel%2Fplugin-transform-member-expression-literals-7.10.4.tgz"],
- ["@babel/plugin-transform-modules-amd", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-amd%2Fdownload%2F%40babel%2Fplugin-transform-modules-amd-7.10.5.tgz"],
- ["@babel/plugin-transform-modules-commonjs", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-commonjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-commonjs-7.10.4.tgz"],
- ["@babel/plugin-transform-modules-systemjs", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-systemjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-systemjs-7.10.5.tgz"],
- ["@babel/plugin-transform-modules-umd", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-umd%2Fdownload%2F%40babel%2Fplugin-transform-modules-umd-7.10.4.tgz"],
- ["@babel/plugin-transform-named-capturing-groups-regex", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-named-capturing-groups-regex%2Fdownload%2F%40babel%2Fplugin-transform-named-capturing-groups-regex-7.10.4.tgz"],
- ["@babel/plugin-transform-new-target", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-new-target%2Fdownload%2F%40babel%2Fplugin-transform-new-target-7.10.4.tgz"],
- ["@babel/plugin-transform-object-super", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-object-super%2Fdownload%2F%40babel%2Fplugin-transform-object-super-7.10.4.tgz"],
- ["@babel/plugin-transform-parameters", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-parameters%2Fdownload%2F%40babel%2Fplugin-transform-parameters-7.10.5.tgz"],
- ["@babel/plugin-transform-property-literals", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-property-literals%2Fdownload%2F%40babel%2Fplugin-transform-property-literals-7.10.4.tgz"],
- ["@babel/plugin-transform-regenerator", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-regenerator%2Fdownload%2F%40babel%2Fplugin-transform-regenerator-7.10.4.tgz"],
- ["@babel/plugin-transform-reserved-words", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-reserved-words%2Fdownload%2F%40babel%2Fplugin-transform-reserved-words-7.10.4.tgz"],
- ["@babel/plugin-transform-shorthand-properties", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-shorthand-properties%2Fdownload%2F%40babel%2Fplugin-transform-shorthand-properties-7.10.4.tgz"],
- ["@babel/plugin-transform-spread", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-spread%2Fdownload%2F%40babel%2Fplugin-transform-spread-7.10.4.tgz"],
- ["@babel/plugin-transform-sticky-regex", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-sticky-regex%2Fdownload%2F%40babel%2Fplugin-transform-sticky-regex-7.10.4.tgz"],
- ["@babel/plugin-transform-template-literals", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-template-literals%2Fdownload%2F%40babel%2Fplugin-transform-template-literals-7.10.5.tgz"],
- ["@babel/plugin-transform-typeof-symbol", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-typeof-symbol%2Fdownload%2F%40babel%2Fplugin-transform-typeof-symbol-7.10.4.tgz"],
- ["@babel/plugin-transform-unicode-escapes", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-escapes%2Fdownload%2F%40babel%2Fplugin-transform-unicode-escapes-7.10.4.tgz"],
- ["@babel/plugin-transform-unicode-regex", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-regex%2Fdownload%2F%40babel%2Fplugin-transform-unicode-regex-7.10.4.tgz"],
- ["@babel/preset-modules", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:0.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-modules%2Fdownload%2F%40babel%2Fpreset-modules-0.1.3.tgz"],
- ["@babel/types", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.10.5.tgz"],
+ ["@babel/plugin-syntax-numeric-separator", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-numeric-separator%2Fdownload%2F%40babel%2Fplugin-syntax-numeric-separator-7.10.4.tgz"],
+ ["@babel/plugin-syntax-object-rest-spread", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-syntax-object-rest-spread-7.8.3.tgz"],
+ ["@babel/plugin-syntax-optional-catch-binding", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-syntax-optional-catch-binding-7.8.3.tgz"],
+ ["@babel/plugin-syntax-optional-chaining", "virtual:532709048cb003cd2417daa5fea56a95b3adea6f1c98f15bbeccd431c941ab5303512f56d976e8c33d619655e94e289d317ca2dbc731adc82d3687ee5a2dd94b#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-chaining%2Fdownload%2F%40babel%2Fplugin-syntax-optional-chaining-7.8.3.tgz"],
+ ["@babel/plugin-syntax-top-level-await", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-top-level-await%2Fdownload%2F%40babel%2Fplugin-syntax-top-level-await-7.10.4.tgz"],
+ ["@babel/plugin-transform-arrow-functions", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-arrow-functions%2Fdownload%2F%40babel%2Fplugin-transform-arrow-functions-7.10.4.tgz"],
+ ["@babel/plugin-transform-async-to-generator", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-async-to-generator%2Fdownload%2F%40babel%2Fplugin-transform-async-to-generator-7.10.4.tgz"],
+ ["@babel/plugin-transform-block-scoped-functions", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoped-functions%2Fdownload%2F%40babel%2Fplugin-transform-block-scoped-functions-7.10.4.tgz"],
+ ["@babel/plugin-transform-block-scoping", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoping%2Fdownload%2F%40babel%2Fplugin-transform-block-scoping-7.10.5.tgz"],
+ ["@babel/plugin-transform-classes", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-classes%2Fdownload%2F%40babel%2Fplugin-transform-classes-7.10.4.tgz"],
+ ["@babel/plugin-transform-computed-properties", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-computed-properties%2Fdownload%2F%40babel%2Fplugin-transform-computed-properties-7.10.4.tgz"],
+ ["@babel/plugin-transform-destructuring", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-destructuring%2Fdownload%2F%40babel%2Fplugin-transform-destructuring-7.10.4.tgz"],
+ ["@babel/plugin-transform-dotall-regex", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-dotall-regex%2Fdownload%2F%40babel%2Fplugin-transform-dotall-regex-7.10.4.tgz"],
+ ["@babel/plugin-transform-duplicate-keys", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-duplicate-keys%2Fdownload%2F%40babel%2Fplugin-transform-duplicate-keys-7.10.4.tgz"],
+ ["@babel/plugin-transform-exponentiation-operator", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-exponentiation-operator%2Fdownload%2F%40babel%2Fplugin-transform-exponentiation-operator-7.10.4.tgz"],
+ ["@babel/plugin-transform-for-of", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-for-of%2Fdownload%2F%40babel%2Fplugin-transform-for-of-7.10.4.tgz"],
+ ["@babel/plugin-transform-function-name", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-function-name%2Fdownload%2F%40babel%2Fplugin-transform-function-name-7.10.4.tgz"],
+ ["@babel/plugin-transform-literals", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-literals%2Fdownload%2F%40babel%2Fplugin-transform-literals-7.10.4.tgz"],
+ ["@babel/plugin-transform-member-expression-literals", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-member-expression-literals%2Fdownload%2F%40babel%2Fplugin-transform-member-expression-literals-7.10.4.tgz"],
+ ["@babel/plugin-transform-modules-amd", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-amd%2Fdownload%2F%40babel%2Fplugin-transform-modules-amd-7.10.5.tgz"],
+ ["@babel/plugin-transform-modules-commonjs", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-commonjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-commonjs-7.10.4.tgz"],
+ ["@babel/plugin-transform-modules-systemjs", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-systemjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-systemjs-7.10.5.tgz"],
+ ["@babel/plugin-transform-modules-umd", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-umd%2Fdownload%2F%40babel%2Fplugin-transform-modules-umd-7.10.4.tgz"],
+ ["@babel/plugin-transform-named-capturing-groups-regex", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-named-capturing-groups-regex%2Fdownload%2F%40babel%2Fplugin-transform-named-capturing-groups-regex-7.10.4.tgz"],
+ ["@babel/plugin-transform-new-target", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-new-target%2Fdownload%2F%40babel%2Fplugin-transform-new-target-7.10.4.tgz"],
+ ["@babel/plugin-transform-object-super", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-object-super%2Fdownload%2F%40babel%2Fplugin-transform-object-super-7.10.4.tgz"],
+ ["@babel/plugin-transform-parameters", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-parameters%2Fdownload%2F%40babel%2Fplugin-transform-parameters-7.10.5.tgz"],
+ ["@babel/plugin-transform-property-literals", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-property-literals%2Fdownload%2F%40babel%2Fplugin-transform-property-literals-7.10.4.tgz"],
+ ["@babel/plugin-transform-regenerator", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-regenerator%2Fdownload%2F%40babel%2Fplugin-transform-regenerator-7.10.4.tgz"],
+ ["@babel/plugin-transform-reserved-words", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-reserved-words%2Fdownload%2F%40babel%2Fplugin-transform-reserved-words-7.10.4.tgz"],
+ ["@babel/plugin-transform-shorthand-properties", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-shorthand-properties%2Fdownload%2F%40babel%2Fplugin-transform-shorthand-properties-7.10.4.tgz"],
+ ["@babel/plugin-transform-spread", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-spread%2Fdownload%2F%40babel%2Fplugin-transform-spread-7.11.0.tgz"],
+ ["@babel/plugin-transform-sticky-regex", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-sticky-regex%2Fdownload%2F%40babel%2Fplugin-transform-sticky-regex-7.10.4.tgz"],
+ ["@babel/plugin-transform-template-literals", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-template-literals%2Fdownload%2F%40babel%2Fplugin-transform-template-literals-7.10.5.tgz"],
+ ["@babel/plugin-transform-typeof-symbol", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-typeof-symbol%2Fdownload%2F%40babel%2Fplugin-transform-typeof-symbol-7.10.4.tgz"],
+ ["@babel/plugin-transform-unicode-escapes", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-escapes%2Fdownload%2F%40babel%2Fplugin-transform-unicode-escapes-7.10.4.tgz"],
+ ["@babel/plugin-transform-unicode-regex", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-regex%2Fdownload%2F%40babel%2Fplugin-transform-unicode-regex-7.10.4.tgz"],
+ ["@babel/preset-modules", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:0.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-modules%2Fdownload%2F%40babel%2Fpreset-modules-0.1.3.tgz"],
+ ["@babel/types", "npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.11.0.tgz"],
["browserslist", "npm:4.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbrowserslist%2Fdownload%2Fbrowserslist-4.13.0.tgz"],
["core-js-compat", "npm:3.6.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js-compat%2Fdownload%2Fcore-js-compat-3.6.5.tgz"],
["invariant", "npm:2.2.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Finvariant%2Fdownload%2Finvariant-2.2.4.tgz"],
@@ -1865,14 +2808,30 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@babel/preset-modules", [
- ["virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:0.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-modules%2Fdownload%2F%40babel%2Fpreset-modules-0.1.3.tgz", {
- "packageLocation": "./.yarn/$$virtual/@babel-preset-modules-virtual-6bc54b7a13/0/cache/@babel-preset-modules-npm-0.1.3-291f9bf1e6-341c13de18.zip/node_modules/@babel/preset-modules/",
+ ["virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:0.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-modules%2Fdownload%2F%40babel%2Fpreset-modules-0.1.3.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-preset-modules-virtual-1cce6b1a7a/0/cache/@babel-preset-modules-npm-0.1.3-291f9bf1e6-341c13de18.zip/node_modules/@babel/preset-modules/",
"packageDependencies": [
- ["@babel/preset-modules", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:0.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-modules%2Fdownload%2F%40babel%2Fpreset-modules-0.1.3.tgz"],
+ ["@babel/preset-modules", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:0.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-modules%2Fdownload%2F%40babel%2Fpreset-modules-0.1.3.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
- ["@babel/plugin-proposal-unicode-property-regex", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-unicode-property-regex%2Fdownload%2F%40babel%2Fplugin-proposal-unicode-property-regex-7.10.4.tgz"],
- ["@babel/plugin-transform-dotall-regex", "virtual:5656a0f4b5c94a664c83f375fa483a1fd9e04cd8810a69d05ad7f6f2a813ca4b7a4d9d0df8bd15bf87c7021e96797fa7358948c082385881a19a655f3342dbc4#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-dotall-regex%2Fdownload%2F%40babel%2Fplugin-transform-dotall-regex-7.10.4.tgz"],
+ ["@babel/plugin-proposal-unicode-property-regex", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-unicode-property-regex%2Fdownload%2F%40babel%2Fplugin-proposal-unicode-property-regex-7.10.4.tgz"],
+ ["@babel/plugin-transform-dotall-regex", "virtual:068c8b8eda7836ec02bd52f20a7e0b5a9fb43cca73532f0b94637b3326d8e95f3d5360454eb58e6aaca096dd999152c8a1103bd512277ff9a6b814a464b37e0f#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-dotall-regex%2Fdownload%2F%40babel%2Fplugin-transform-dotall-regex-7.10.4.tgz"],
+ ["@babel/types", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.10.5.tgz"],
+ ["esutils", "npm:2.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fesutils%2Fdownload%2Fesutils-2.0.3.tgz"]
+ ],
+ "packagePeers": [
+ "@babel/core"
+ ],
+ "linkType": "HARD",
+ }],
+ ["virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:0.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-modules%2Fdownload%2F%40babel%2Fpreset-modules-0.1.3.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@babel-preset-modules-virtual-5e2fb58445/0/cache/@babel-preset-modules-npm-0.1.3-291f9bf1e6-341c13de18.zip/node_modules/@babel/preset-modules/",
+ "packageDependencies": [
+ ["@babel/preset-modules", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:0.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-modules%2Fdownload%2F%40babel%2Fpreset-modules-0.1.3.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
+ ["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
+ ["@babel/plugin-proposal-unicode-property-regex", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-unicode-property-regex%2Fdownload%2F%40babel%2Fplugin-proposal-unicode-property-regex-7.10.4.tgz"],
+ ["@babel/plugin-transform-dotall-regex", "virtual:fe72b7f1f81cd2f32bf151022eaf69105ad6da247f644cc230a7476462296ddf3486a2e9343f0a95d7807b538ec1cbd7e68f6722dda540a3e9b7570a9ba0181c#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-dotall-regex%2Fdownload%2F%40babel%2Fplugin-transform-dotall-regex-7.10.4.tgz"],
["@babel/types", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.10.5.tgz"],
["esutils", "npm:2.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fesutils%2Fdownload%2Fesutils-2.0.3.tgz"]
],
@@ -1887,7 +2846,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./.yarn/$$virtual/@babel-preset-react-virtual-1953e0512b/0/cache/@babel-preset-react-npm-7.10.4-0ae2d4c767-233b242753.zip/node_modules/@babel/preset-react/",
"packageDependencies": [
["@babel/preset-react", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-react%2Fdownload%2F%40babel%2Fpreset-react-7.10.4.tgz"],
- ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
["@babel/plugin-transform-react-display-name", "virtual:1953e0512b6e30a17e7a43e1b60ee941d9c4f185eae0e05cdcee8720ba51d9e54edce139cdd791820e0b4691963bc37593b2c3576801c98047877349c5824ef7#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-react-display-name%2Fdownload%2F%40babel%2Fplugin-transform-react-display-name-7.10.4.tgz"],
["@babel/plugin-transform-react-jsx", "virtual:1953e0512b6e30a17e7a43e1b60ee941d9c4f185eae0e05cdcee8720ba51d9e54edce139cdd791820e0b4691963bc37593b2c3576801c98047877349c5824ef7#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-react-jsx%2Fdownload%2F%40babel%2Fplugin-transform-react-jsx-7.10.4.tgz"],
@@ -1907,7 +2866,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./.yarn/$$virtual/@babel-preset-typescript-virtual-6fec19edd8/0/cache/@babel-preset-typescript-npm-7.10.4-05c5190234-e14357988c.zip/node_modules/@babel/preset-typescript/",
"packageDependencies": [
["@babel/preset-typescript", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-typescript%2Fdownload%2F%40babel%2Fpreset-typescript-7.10.4.tgz"],
- ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
["@babel/helper-plugin-utils", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"],
["@babel/plugin-transform-typescript", "virtual:6fec19edd8abb0c228b7761c4f066e29e1dcdd569dfaabffcb8721701d685f707551e64dbfb2a8a84b999f8a6a4a28c0954962f30bc5802165d47de83e24991f#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-typescript%2Fdownload%2F%40babel%2Fplugin-transform-typescript-7.10.5.tgz"]
],
@@ -1966,6 +2925,22 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["lodash", "npm:4.17.19::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.19.tgz"]
],
"linkType": "HARD",
+ }],
+ ["npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftraverse%2Fdownload%2F%40babel%2Ftraverse-7.11.0.tgz", {
+ "packageLocation": "./.yarn/cache/@babel-traverse-npm-7.11.0-35c4351df6-81e4bb3020.zip/node_modules/@babel/traverse/",
+ "packageDependencies": [
+ ["@babel/traverse", "npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftraverse%2Fdownload%2F%40babel%2Ftraverse-7.11.0.tgz"],
+ ["@babel/code-frame", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcode-frame%2Fdownload%2F%40babel%2Fcode-frame-7.10.4.tgz"],
+ ["@babel/generator", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fgenerator%2Fdownload%2F%40babel%2Fgenerator-7.11.4.tgz"],
+ ["@babel/helper-function-name", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-function-name%2Fdownload%2F%40babel%2Fhelper-function-name-7.10.4.tgz"],
+ ["@babel/helper-split-export-declaration", "npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-split-export-declaration%2Fdownload%2F%40babel%2Fhelper-split-export-declaration-7.11.0.tgz"],
+ ["@babel/parser", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fparser%2Fdownload%2F%40babel%2Fparser-7.11.4.tgz"],
+ ["@babel/types", "npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.11.0.tgz"],
+ ["debug", "virtual:1e7fd7cbf468e9bdfe63ec86a342d405dc91ac84c8bb9894805983f8c23226bd5a88ff6423eed3317b91c46b7e9258b9c2030fa7275a62d19703cdbb018c2efc#npm:4.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz"],
+ ["globals", "npm:11.12.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fglobals%2Fdownload%2Fglobals-11.12.0.tgz"],
+ ["lodash", "npm:4.17.19::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.19.tgz"]
+ ],
+ "linkType": "HARD",
}]
]],
["@babel/types", [
@@ -1978,6 +2953,16 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["to-fast-properties", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fto-fast-properties%2Fdownload%2Fto-fast-properties-2.0.0.tgz"]
],
"linkType": "HARD",
+ }],
+ ["npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.11.0.tgz", {
+ "packageLocation": "./.yarn/cache/@babel-types-npm-7.11.0-b26eec3349-46e2fcd49d.zip/node_modules/@babel/types/",
+ "packageDependencies": [
+ ["@babel/types", "npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.11.0.tgz"],
+ ["@babel/helper-validator-identifier", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-validator-identifier%2Fdownload%2F%40babel%2Fhelper-validator-identifier-7.10.4.tgz"],
+ ["lodash", "npm:4.17.19::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.19.tgz"],
+ ["to-fast-properties", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fto-fast-properties%2Fdownload%2Fto-fast-properties-2.0.0.tgz"]
+ ],
+ "linkType": "HARD",
}]
]],
["@csstools/convert-colors", [
@@ -2279,6 +3264,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD",
}]
]],
+ ["@types/html-minifier-terser", [
+ ["npm:5.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fhtml-minifier-terser%2Fdownload%2F%40types%2Fhtml-minifier-terser-5.1.0.tgz", {
+ "packageLocation": "./.yarn/cache/@types-html-minifier-terser-npm-5.1.0-6fb2bf10b0-e07f30cf9b.zip/node_modules/@types/html-minifier-terser/",
+ "packageDependencies": [
+ ["@types/html-minifier-terser", "npm:5.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fhtml-minifier-terser%2Fdownload%2F%40types%2Fhtml-minifier-terser-5.1.0.tgz"]
+ ],
+ "linkType": "HARD",
+ }]
+ ]],
["@types/http-cache-semantics", [
["npm:4.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fhttp-cache-semantics%2Fdownload%2F%40types%2Fhttp-cache-semantics-4.0.0.tgz", {
"packageLocation": "./.yarn/cache/@types-http-cache-semantics-npm-4.0.0-c054c89f34-e16fae56d4.zip/node_modules/@types/http-cache-semantics/",
@@ -2308,10 +3302,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@types/lodash", [
- ["npm:4.14.157::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Flodash%2Fdownload%2F%40types%2Flodash-4.14.157.tgz", {
- "packageLocation": "./.yarn/cache/@types-lodash-npm-4.14.157-23729597e4-ea8d890a4d.zip/node_modules/@types/lodash/",
+ ["npm:4.14.159::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Flodash%2Fdownload%2F%40types%2Flodash-4.14.159.tgz", {
+ "packageLocation": "./.yarn/cache/@types-lodash-npm-4.14.159-de2da0836d-15fc1b6909.zip/node_modules/@types/lodash/",
"packageDependencies": [
- ["@types/lodash", "npm:4.14.157::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Flodash%2Fdownload%2F%40types%2Flodash-4.14.157.tgz"]
+ ["@types/lodash", "npm:4.14.159::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Flodash%2Fdownload%2F%40types%2Flodash-4.14.159.tgz"]
],
"linkType": "HARD",
}]
@@ -2339,6 +3333,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@types/node", "npm:14.0.23::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-14.0.23.tgz"]
],
"linkType": "HARD",
+ }],
+ ["npm:14.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-14.6.0.tgz", {
+ "packageLocation": "./.yarn/cache/@types-node-npm-14.6.0-8de88b91df-ff23553ab7.zip/node_modules/@types/node/",
+ "packageDependencies": [
+ ["@types/node", "npm:14.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-14.6.0.tgz"]
+ ],
+ "linkType": "HARD",
}]
]],
["@types/prop-types", [
@@ -2359,6 +3360,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["csstype", "npm:2.6.11::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcsstype%2Fdownload%2Fcsstype-2.6.11.tgz"]
],
"linkType": "HARD",
+ }],
+ ["npm:16.9.46::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact%2Fdownload%2F%40types%2Freact-16.9.46.tgz", {
+ "packageLocation": "./.yarn/cache/@types-react-npm-16.9.46-49309c9681-ad8d07195d.zip/node_modules/@types/react/",
+ "packageDependencies": [
+ ["@types/react", "npm:16.9.46::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact%2Fdownload%2F%40types%2Freact-16.9.46.tgz"],
+ ["@types/prop-types", "npm:15.7.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fprop-types%2Fdownload%2F%40types%2Fprop-types-15.7.3.tgz"],
+ ["csstype", "npm:3.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcsstype%2Fdownload%2Fcsstype-3.0.2.tgz"]
+ ],
+ "linkType": "HARD",
}]
]],
["@types/react-dom", [
@@ -2405,10 +3415,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@types/reactstrap", [
- ["npm:8.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freactstrap%2Fdownload%2F%40types%2Freactstrap-8.5.0.tgz", {
- "packageLocation": "./.yarn/cache/@types-reactstrap-npm-8.5.0-daffde16db-5c8bf89b4f.zip/node_modules/@types/reactstrap/",
+ ["npm:8.5.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freactstrap%2Fdownload%2F%40types%2Freactstrap-8.5.1.tgz", {
+ "packageLocation": "./.yarn/cache/@types-reactstrap-npm-8.5.1-9008a6014f-87b383af72.zip/node_modules/@types/reactstrap/",
"packageDependencies": [
- ["@types/reactstrap", "npm:8.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freactstrap%2Fdownload%2F%40types%2Freactstrap-8.5.0.tgz"],
+ ["@types/reactstrap", "npm:8.5.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freactstrap%2Fdownload%2F%40types%2Freactstrap-8.5.1.tgz"],
["@types/react", "npm:16.9.43::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact%2Fdownload%2F%40types%2Freact-16.9.43.tgz"],
["popper.js", "npm:1.16.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpopper.js%2Fdownload%2Fpopper.js-1.16.1.tgz"]
],
@@ -2509,19 +3519,19 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@typescript-eslint/eslint-plugin", [
- ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Feslint-plugin%2Fdownload%2F%40typescript-eslint%2Feslint-plugin-3.6.1.tgz", {
- "packageLocation": "./.yarn/$$virtual/@typescript-eslint-eslint-plugin-virtual-7711a57149/0/cache/@typescript-eslint-eslint-plugin-npm-3.6.1-45b2fd9fd6-eb4c47eb0a.zip/node_modules/@typescript-eslint/eslint-plugin/",
+ ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Feslint-plugin%2Fdownload%2F%40typescript-eslint%2Feslint-plugin-3.9.1.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@typescript-eslint-eslint-plugin-virtual-6b090f53c6/0/cache/@typescript-eslint-eslint-plugin-npm-3.9.1-2cda56b7cb-252bab346c.zip/node_modules/@typescript-eslint/eslint-plugin/",
"packageDependencies": [
- ["@typescript-eslint/eslint-plugin", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Feslint-plugin%2Fdownload%2F%40typescript-eslint%2Feslint-plugin-3.6.1.tgz"],
- ["@typescript-eslint/experimental-utils", "virtual:7711a57149a350acf71614f15e4d5dde0ed80fd3f6b9aac11b49aa0f1900f1b05731e0e43a37fe8f0fa730942e0de5e80e4aca1a0df7ded2ab03d0bb11716c42#npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fexperimental-utils%2Fdownload%2F%40typescript-eslint%2Fexperimental-utils-3.6.1.tgz"],
- ["@typescript-eslint/parser", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fparser%2Fdownload%2F%40typescript-eslint%2Fparser-3.6.1.tgz"],
+ ["@typescript-eslint/eslint-plugin", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Feslint-plugin%2Fdownload%2F%40typescript-eslint%2Feslint-plugin-3.9.1.tgz"],
+ ["@typescript-eslint/experimental-utils", "virtual:6b090f53c60ffa0b7aaef0ced1caa498287b02ac23431999e7b6354a77c6335756f1b98cede1091b7477651df82c3e43da90a593747dbb5c19e306c383157b84#npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fexperimental-utils%2Fdownload%2F%40typescript-eslint%2Fexperimental-utils-3.9.1.tgz"],
+ ["@typescript-eslint/parser", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fparser%2Fdownload%2F%40typescript-eslint%2Fparser-3.9.1.tgz"],
["debug", "virtual:1e7fd7cbf468e9bdfe63ec86a342d405dc91ac84c8bb9894805983f8c23226bd5a88ff6423eed3317b91c46b7e9258b9c2030fa7275a62d19703cdbb018c2efc#npm:4.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz"],
- ["eslint", "npm:7.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.5.0.tgz"],
+ ["eslint", "npm:7.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.7.0.tgz"],
["functional-red-black-tree", "npm:1.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffunctional-red-black-tree%2Fdownload%2Ffunctional-red-black-tree-1.0.1.tgz"],
["regexpp", "npm:3.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fregexpp%2Fdownload%2Fregexpp-3.1.0.tgz"],
["semver", "npm:7.3.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-7.3.2.tgz"],
- ["tsutils", "virtual:7711a57149a350acf71614f15e4d5dde0ed80fd3f6b9aac11b49aa0f1900f1b05731e0e43a37fe8f0fa730942e0de5e80e4aca1a0df7ded2ab03d0bb11716c42#npm:3.17.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsutils%2Fdownload%2Ftsutils-3.17.1.tgz"],
- ["typescript", "patch:typescript@npm%3A3.9.7%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-3.9.7.tgz#builtin<compat/typescript>::version=3.9.7&hash=5b02a2"]
+ ["tsutils", "virtual:6b090f53c60ffa0b7aaef0ced1caa498287b02ac23431999e7b6354a77c6335756f1b98cede1091b7477651df82c3e43da90a593747dbb5c19e306c383157b84#npm:3.17.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsutils%2Fdownload%2Ftsutils-3.17.1.tgz"],
+ ["typescript", "patch:typescript@npm%3A4.0.2%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-4.0.2.tgz#builtin<compat/typescript>::version=4.0.2&hash=5b02a2"]
],
"packagePeers": [
"eslint",
@@ -2532,14 +3542,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@typescript-eslint/experimental-utils", [
- ["virtual:7711a57149a350acf71614f15e4d5dde0ed80fd3f6b9aac11b49aa0f1900f1b05731e0e43a37fe8f0fa730942e0de5e80e4aca1a0df7ded2ab03d0bb11716c42#npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fexperimental-utils%2Fdownload%2F%40typescript-eslint%2Fexperimental-utils-3.6.1.tgz", {
- "packageLocation": "./.yarn/$$virtual/@typescript-eslint-experimental-utils-virtual-d663d22ed2/0/cache/@typescript-eslint-experimental-utils-npm-3.6.1-e8ef1c87ef-dd8bd15c20.zip/node_modules/@typescript-eslint/experimental-utils/",
+ ["virtual:6b090f53c60ffa0b7aaef0ced1caa498287b02ac23431999e7b6354a77c6335756f1b98cede1091b7477651df82c3e43da90a593747dbb5c19e306c383157b84#npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fexperimental-utils%2Fdownload%2F%40typescript-eslint%2Fexperimental-utils-3.9.1.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@typescript-eslint-experimental-utils-virtual-df4286ad2d/0/cache/@typescript-eslint-experimental-utils-npm-3.9.1-40f2b41373-8092e411ad.zip/node_modules/@typescript-eslint/experimental-utils/",
"packageDependencies": [
- ["@typescript-eslint/experimental-utils", "virtual:7711a57149a350acf71614f15e4d5dde0ed80fd3f6b9aac11b49aa0f1900f1b05731e0e43a37fe8f0fa730942e0de5e80e4aca1a0df7ded2ab03d0bb11716c42#npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fexperimental-utils%2Fdownload%2F%40typescript-eslint%2Fexperimental-utils-3.6.1.tgz"],
+ ["@typescript-eslint/experimental-utils", "virtual:6b090f53c60ffa0b7aaef0ced1caa498287b02ac23431999e7b6354a77c6335756f1b98cede1091b7477651df82c3e43da90a593747dbb5c19e306c383157b84#npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fexperimental-utils%2Fdownload%2F%40typescript-eslint%2Fexperimental-utils-3.9.1.tgz"],
["@types/json-schema", "npm:7.0.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fjson-schema%2Fdownload%2F%40types%2Fjson-schema-7.0.5.tgz"],
- ["@typescript-eslint/types", "npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypes%2Fdownload%2F%40typescript-eslint%2Ftypes-3.6.1.tgz"],
- ["@typescript-eslint/typescript-estree", "virtual:d663d22ed2f89a4907815553b6de283157bc2c77015d715f9ffadc79d83c0d7ba677b1064ef329f16d3f8decc6c81992f449e2dc1566d137e78f1bdb8a819d4f#npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypescript-estree%2Fdownload%2F%40typescript-eslint%2Ftypescript-estree-3.6.1.tgz"],
- ["eslint", "npm:7.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.5.0.tgz"],
+ ["@typescript-eslint/types", "npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypes%2Fdownload%2F%40typescript-eslint%2Ftypes-3.9.1.tgz"],
+ ["@typescript-eslint/typescript-estree", "virtual:df4286ad2dbd8990171b878316c1fe9598308406e0387a68bb607fb89d218a32cd304b92b54ad46892acd7ac98d4f454c214ce71de95737e5e709e231b69559a#npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypescript-estree%2Fdownload%2F%40typescript-eslint%2Ftypescript-estree-3.9.1.tgz"],
+ ["eslint", "npm:7.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.7.0.tgz"],
["eslint-scope", "npm:5.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-scope%2Fdownload%2Feslint-scope-5.1.0.tgz"],
["eslint-utils", "npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-utils%2Fdownload%2Feslint-utils-2.1.0.tgz"]
],
@@ -2550,17 +3560,17 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@typescript-eslint/parser", [
- ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fparser%2Fdownload%2F%40typescript-eslint%2Fparser-3.6.1.tgz", {
- "packageLocation": "./.yarn/$$virtual/@typescript-eslint-parser-virtual-4730845da1/0/cache/@typescript-eslint-parser-npm-3.6.1-088715d20b-0fbb334ab4.zip/node_modules/@typescript-eslint/parser/",
+ ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fparser%2Fdownload%2F%40typescript-eslint%2Fparser-3.9.1.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@typescript-eslint-parser-virtual-da4b860a85/0/cache/@typescript-eslint-parser-npm-3.9.1-b73c5ce5bf-ed9a482969.zip/node_modules/@typescript-eslint/parser/",
"packageDependencies": [
- ["@typescript-eslint/parser", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fparser%2Fdownload%2F%40typescript-eslint%2Fparser-3.6.1.tgz"],
+ ["@typescript-eslint/parser", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fparser%2Fdownload%2F%40typescript-eslint%2Fparser-3.9.1.tgz"],
["@types/eslint-visitor-keys", "npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Feslint-visitor-keys%2Fdownload%2F%40types%2Feslint-visitor-keys-1.0.0.tgz"],
- ["@typescript-eslint/experimental-utils", "virtual:7711a57149a350acf71614f15e4d5dde0ed80fd3f6b9aac11b49aa0f1900f1b05731e0e43a37fe8f0fa730942e0de5e80e4aca1a0df7ded2ab03d0bb11716c42#npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fexperimental-utils%2Fdownload%2F%40typescript-eslint%2Fexperimental-utils-3.6.1.tgz"],
- ["@typescript-eslint/types", "npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypes%2Fdownload%2F%40typescript-eslint%2Ftypes-3.6.1.tgz"],
- ["@typescript-eslint/typescript-estree", "virtual:4730845da158a7303624c6dc3ba9d8f946b25f40122c3ccdd1bf29f5aef51df7cec01e9f4f32e6a06192dbd4bf05d1e0429fa1089fba5c182cd590f3f0dba8e6#npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypescript-estree%2Fdownload%2F%40typescript-eslint%2Ftypescript-estree-3.6.1.tgz"],
- ["eslint", "npm:7.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.5.0.tgz"],
+ ["@typescript-eslint/experimental-utils", "virtual:6b090f53c60ffa0b7aaef0ced1caa498287b02ac23431999e7b6354a77c6335756f1b98cede1091b7477651df82c3e43da90a593747dbb5c19e306c383157b84#npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fexperimental-utils%2Fdownload%2F%40typescript-eslint%2Fexperimental-utils-3.9.1.tgz"],
+ ["@typescript-eslint/types", "npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypes%2Fdownload%2F%40typescript-eslint%2Ftypes-3.9.1.tgz"],
+ ["@typescript-eslint/typescript-estree", "virtual:da4b860a853ff200ac4ab1f139143c870c7a3642b2e9964b44a445f50c829ca897de6d1c95ed33aa2b04e0f49f3c030468ee540e04dd8c5a3cbd692a0a24d0d4#npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypescript-estree%2Fdownload%2F%40typescript-eslint%2Ftypescript-estree-3.9.1.tgz"],
+ ["eslint", "npm:7.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.7.0.tgz"],
["eslint-visitor-keys", "npm:1.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-visitor-keys%2Fdownload%2Feslint-visitor-keys-1.3.0.tgz"],
- ["typescript", "patch:typescript@npm%3A3.9.7%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-3.9.7.tgz#builtin<compat/typescript>::version=3.9.7&hash=5b02a2"]
+ ["typescript", "patch:typescript@npm%3A4.0.2%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-4.0.2.tgz#builtin<compat/typescript>::version=4.0.2&hash=5b02a2"]
],
"packagePeers": [
"eslint",
@@ -2570,46 +3580,46 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@typescript-eslint/types", [
- ["npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypes%2Fdownload%2F%40typescript-eslint%2Ftypes-3.6.1.tgz", {
- "packageLocation": "./.yarn/cache/@typescript-eslint-types-npm-3.6.1-bc408deea9-c90e36b623.zip/node_modules/@typescript-eslint/types/",
+ ["npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypes%2Fdownload%2F%40typescript-eslint%2Ftypes-3.9.1.tgz", {
+ "packageLocation": "./.yarn/cache/@typescript-eslint-types-npm-3.9.1-cb562eed7e-0591ff7691.zip/node_modules/@typescript-eslint/types/",
"packageDependencies": [
- ["@typescript-eslint/types", "npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypes%2Fdownload%2F%40typescript-eslint%2Ftypes-3.6.1.tgz"]
+ ["@typescript-eslint/types", "npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypes%2Fdownload%2F%40typescript-eslint%2Ftypes-3.9.1.tgz"]
],
"linkType": "HARD",
}]
]],
["@typescript-eslint/typescript-estree", [
- ["virtual:4730845da158a7303624c6dc3ba9d8f946b25f40122c3ccdd1bf29f5aef51df7cec01e9f4f32e6a06192dbd4bf05d1e0429fa1089fba5c182cd590f3f0dba8e6#npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypescript-estree%2Fdownload%2F%40typescript-eslint%2Ftypescript-estree-3.6.1.tgz", {
- "packageLocation": "./.yarn/$$virtual/@typescript-eslint-typescript-estree-virtual-3e8e91bc56/0/cache/@typescript-eslint-typescript-estree-npm-3.6.1-bd9d284919-93eef4a7ac.zip/node_modules/@typescript-eslint/typescript-estree/",
+ ["virtual:da4b860a853ff200ac4ab1f139143c870c7a3642b2e9964b44a445f50c829ca897de6d1c95ed33aa2b04e0f49f3c030468ee540e04dd8c5a3cbd692a0a24d0d4#npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypescript-estree%2Fdownload%2F%40typescript-eslint%2Ftypescript-estree-3.9.1.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@typescript-eslint-typescript-estree-virtual-da7cc4b7f8/0/cache/@typescript-eslint-typescript-estree-npm-3.9.1-79a46ee31e-f9a962b6ff.zip/node_modules/@typescript-eslint/typescript-estree/",
"packageDependencies": [
- ["@typescript-eslint/typescript-estree", "virtual:4730845da158a7303624c6dc3ba9d8f946b25f40122c3ccdd1bf29f5aef51df7cec01e9f4f32e6a06192dbd4bf05d1e0429fa1089fba5c182cd590f3f0dba8e6#npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypescript-estree%2Fdownload%2F%40typescript-eslint%2Ftypescript-estree-3.6.1.tgz"],
- ["@typescript-eslint/types", "npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypes%2Fdownload%2F%40typescript-eslint%2Ftypes-3.6.1.tgz"],
- ["@typescript-eslint/visitor-keys", "npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fvisitor-keys%2Fdownload%2F%40typescript-eslint%2Fvisitor-keys-3.6.1.tgz"],
+ ["@typescript-eslint/typescript-estree", "virtual:da4b860a853ff200ac4ab1f139143c870c7a3642b2e9964b44a445f50c829ca897de6d1c95ed33aa2b04e0f49f3c030468ee540e04dd8c5a3cbd692a0a24d0d4#npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypescript-estree%2Fdownload%2F%40typescript-eslint%2Ftypescript-estree-3.9.1.tgz"],
+ ["@typescript-eslint/types", "npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypes%2Fdownload%2F%40typescript-eslint%2Ftypes-3.9.1.tgz"],
+ ["@typescript-eslint/visitor-keys", "npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fvisitor-keys%2Fdownload%2F%40typescript-eslint%2Fvisitor-keys-3.9.1.tgz"],
["debug", "virtual:1e7fd7cbf468e9bdfe63ec86a342d405dc91ac84c8bb9894805983f8c23226bd5a88ff6423eed3317b91c46b7e9258b9c2030fa7275a62d19703cdbb018c2efc#npm:4.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz"],
["glob", "npm:7.1.6::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fglob%2Fdownload%2Fglob-7.1.6.tgz"],
["is-glob", "npm:4.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-glob%2Fdownload%2Fis-glob-4.0.1.tgz"],
["lodash", "npm:4.17.19::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.19.tgz"],
["semver", "npm:7.3.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-7.3.2.tgz"],
- ["tsutils", "virtual:7711a57149a350acf71614f15e4d5dde0ed80fd3f6b9aac11b49aa0f1900f1b05731e0e43a37fe8f0fa730942e0de5e80e4aca1a0df7ded2ab03d0bb11716c42#npm:3.17.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsutils%2Fdownload%2Ftsutils-3.17.1.tgz"],
- ["typescript", "patch:typescript@npm%3A3.9.7%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-3.9.7.tgz#builtin<compat/typescript>::version=3.9.7&hash=5b02a2"]
+ ["tsutils", "virtual:6b090f53c60ffa0b7aaef0ced1caa498287b02ac23431999e7b6354a77c6335756f1b98cede1091b7477651df82c3e43da90a593747dbb5c19e306c383157b84#npm:3.17.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsutils%2Fdownload%2Ftsutils-3.17.1.tgz"],
+ ["typescript", "patch:typescript@npm%3A4.0.2%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-4.0.2.tgz#builtin<compat/typescript>::version=4.0.2&hash=5b02a2"]
],
"packagePeers": [
"typescript"
],
"linkType": "HARD",
}],
- ["virtual:d663d22ed2f89a4907815553b6de283157bc2c77015d715f9ffadc79d83c0d7ba677b1064ef329f16d3f8decc6c81992f449e2dc1566d137e78f1bdb8a819d4f#npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypescript-estree%2Fdownload%2F%40typescript-eslint%2Ftypescript-estree-3.6.1.tgz", {
- "packageLocation": "./.yarn/$$virtual/@typescript-eslint-typescript-estree-virtual-3188411791/0/cache/@typescript-eslint-typescript-estree-npm-3.6.1-bd9d284919-93eef4a7ac.zip/node_modules/@typescript-eslint/typescript-estree/",
+ ["virtual:df4286ad2dbd8990171b878316c1fe9598308406e0387a68bb607fb89d218a32cd304b92b54ad46892acd7ac98d4f454c214ce71de95737e5e709e231b69559a#npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypescript-estree%2Fdownload%2F%40typescript-eslint%2Ftypescript-estree-3.9.1.tgz", {
+ "packageLocation": "./.yarn/$$virtual/@typescript-eslint-typescript-estree-virtual-74f3ce4730/0/cache/@typescript-eslint-typescript-estree-npm-3.9.1-79a46ee31e-f9a962b6ff.zip/node_modules/@typescript-eslint/typescript-estree/",
"packageDependencies": [
- ["@typescript-eslint/typescript-estree", "virtual:d663d22ed2f89a4907815553b6de283157bc2c77015d715f9ffadc79d83c0d7ba677b1064ef329f16d3f8decc6c81992f449e2dc1566d137e78f1bdb8a819d4f#npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypescript-estree%2Fdownload%2F%40typescript-eslint%2Ftypescript-estree-3.6.1.tgz"],
- ["@typescript-eslint/types", "npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypes%2Fdownload%2F%40typescript-eslint%2Ftypes-3.6.1.tgz"],
- ["@typescript-eslint/visitor-keys", "npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fvisitor-keys%2Fdownload%2F%40typescript-eslint%2Fvisitor-keys-3.6.1.tgz"],
+ ["@typescript-eslint/typescript-estree", "virtual:df4286ad2dbd8990171b878316c1fe9598308406e0387a68bb607fb89d218a32cd304b92b54ad46892acd7ac98d4f454c214ce71de95737e5e709e231b69559a#npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypescript-estree%2Fdownload%2F%40typescript-eslint%2Ftypescript-estree-3.9.1.tgz"],
+ ["@typescript-eslint/types", "npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypes%2Fdownload%2F%40typescript-eslint%2Ftypes-3.9.1.tgz"],
+ ["@typescript-eslint/visitor-keys", "npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fvisitor-keys%2Fdownload%2F%40typescript-eslint%2Fvisitor-keys-3.9.1.tgz"],
["debug", "virtual:1e7fd7cbf468e9bdfe63ec86a342d405dc91ac84c8bb9894805983f8c23226bd5a88ff6423eed3317b91c46b7e9258b9c2030fa7275a62d19703cdbb018c2efc#npm:4.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz"],
["glob", "npm:7.1.6::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fglob%2Fdownload%2Fglob-7.1.6.tgz"],
["is-glob", "npm:4.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-glob%2Fdownload%2Fis-glob-4.0.1.tgz"],
["lodash", "npm:4.17.19::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.19.tgz"],
["semver", "npm:7.3.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-7.3.2.tgz"],
- ["tsutils", "virtual:3188411791b9b17064a0b4716d5f9f317fab9aca03a2adad8703c8c0c871289085f9fb2d89f69d61307afa5661ddcb03fe2b5bfb5820dc0232403037c0dac9cb#npm:3.17.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsutils%2Fdownload%2Ftsutils-3.17.1.tgz"],
+ ["tsutils", "virtual:74f3ce4730be82a39c05577948e092efbe436415fbae850d9d5d07bee35df41e3ecfd8a5b58d019a2990d0c5ad4c8a28fe10a468f8ed2307a1f4ca468609e708#npm:3.17.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsutils%2Fdownload%2Ftsutils-3.17.1.tgz"],
["typescript", null]
],
"packagePeers": [
@@ -2619,10 +3629,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["@typescript-eslint/visitor-keys", [
- ["npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fvisitor-keys%2Fdownload%2F%40typescript-eslint%2Fvisitor-keys-3.6.1.tgz", {
- "packageLocation": "./.yarn/cache/@typescript-eslint-visitor-keys-npm-3.6.1-9acde13e24-041b3af065.zip/node_modules/@typescript-eslint/visitor-keys/",
+ ["npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fvisitor-keys%2Fdownload%2F%40typescript-eslint%2Fvisitor-keys-3.9.1.tgz", {
+ "packageLocation": "./.yarn/cache/@typescript-eslint-visitor-keys-npm-3.9.1-e091c000de-9e54d3a37a.zip/node_modules/@typescript-eslint/visitor-keys/",
"packageDependencies": [
- ["@typescript-eslint/visitor-keys", "npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fvisitor-keys%2Fdownload%2F%40typescript-eslint%2Fvisitor-keys-3.6.1.tgz"],
+ ["@typescript-eslint/visitor-keys", "npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fvisitor-keys%2Fdownload%2F%40typescript-eslint%2Fvisitor-keys-3.9.1.tgz"],
["eslint-visitor-keys", "npm:1.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-visitor-keys%2Fdownload%2Feslint-visitor-keys-1.3.0.tgz"]
],
"linkType": "HARD",
@@ -2954,10 +3964,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["chalk", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-3.0.0.tgz"],
["clipanion", "npm:2.4.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fclipanion%2Fdownload%2Fclipanion-2.4.2.tgz"],
["comment-json", "npm:2.4.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcomment-json%2Fdownload%2Fcomment-json-2.4.2.tgz"],
- ["eslint", "npm:7.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.5.0.tgz"],
+ ["eslint", "npm:7.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.7.0.tgz"],
["lodash", "npm:4.17.19::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.19.tgz"],
["tslib", "npm:1.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftslib%2Fdownload%2Ftslib-1.13.0.tgz"],
- ["typescript", "patch:typescript@npm%3A3.9.7%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-3.9.7.tgz#builtin<compat/typescript>::version=3.9.7&hash=5b02a2"]
+ ["typescript", "patch:typescript@npm%3A4.0.2%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-4.0.2.tgz#builtin<compat/typescript>::version=4.0.2&hash=5b02a2"]
],
"packagePeers": [
"eslint",
@@ -3466,11 +4476,11 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["axios", [
- ["npm:0.19.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.19.2.tgz", {
- "packageLocation": "./.yarn/cache/axios-npm-0.19.2-41340f1b40-bad346deea.zip/node_modules/axios/",
+ ["npm:0.20.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.20.0.tgz", {
+ "packageLocation": "./.yarn/cache/axios-npm-0.20.0-85e8566ade-6cf2e96317.zip/node_modules/axios/",
"packageDependencies": [
- ["axios", "npm:0.19.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.19.2.tgz"],
- ["follow-redirects", "npm:1.5.10::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.5.10.tgz"]
+ ["axios", "npm:0.20.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.20.0.tgz"],
+ ["follow-redirects", "npm:1.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.13.0.tgz"]
],
"linkType": "HARD",
}]
@@ -3502,13 +4512,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./.yarn/$$virtual/babel-loader-virtual-e211b20a54/0/cache/babel-loader-npm-8.1.0-367cb3ea01-f7b236a5f7.zip/node_modules/babel-loader/",
"packageDependencies": [
["babel-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:8.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-loader%2Fdownload%2Fbabel-loader-8.1.0.tgz"],
- ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
["find-cache-dir", "npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-cache-dir%2Fdownload%2Ffind-cache-dir-2.1.0.tgz"],
["loader-utils", "npm:1.4.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-utils%2Fdownload%2Floader-utils-1.4.0.tgz"],
["mkdirp", "npm:0.5.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fmkdirp%2Fdownload%2Fmkdirp-0.5.5.tgz"],
["pify", "npm:4.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpify%2Fdownload%2Fpify-4.0.1.tgz"],
["schema-utils", "npm:2.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fschema-utils%2Fdownload%2Fschema-utils-2.7.0.tgz"],
- ["webpack", "npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz"]
+ ["webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"]
],
"packagePeers": [
"@babel/core",
@@ -3696,13 +4706,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["big.js", [
- ["npm:3.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbig.js%2Fdownload%2Fbig.js-3.2.0.tgz", {
- "packageLocation": "./.yarn/cache/big.js-npm-3.2.0-031cf78174-6f08a28dd4.zip/node_modules/big.js/",
- "packageDependencies": [
- ["big.js", "npm:3.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbig.js%2Fdownload%2Fbig.js-3.2.0.tgz"]
- ],
- "linkType": "HARD",
- }],
["npm:5.2.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbig.js%2Fdownload%2Fbig.js-5.2.2.tgz", {
"packageLocation": "./.yarn/cache/big.js-npm-5.2.2-5ae2b6c67c-ea33d7d256.zip/node_modules/big.js/",
"packageDependencies": [
@@ -3806,10 +4809,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["bootstrap", [
- ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbootstrap%2Fdownload%2Fbootstrap-4.5.0.tgz", {
- "packageLocation": "./.yarn/$$virtual/bootstrap-virtual-0149bd8a87/0/cache/bootstrap-npm-4.5.0-0f060749a1-89284a8d1b.zip/node_modules/bootstrap/",
+ ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.5.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbootstrap%2Fdownload%2Fbootstrap-4.5.2.tgz", {
+ "packageLocation": "./.yarn/$$virtual/bootstrap-virtual-b7d7b7610e/0/cache/bootstrap-npm-4.5.2-128abd58c2-980e7e4ebd.zip/node_modules/bootstrap/",
"packageDependencies": [
- ["bootstrap", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbootstrap%2Fdownload%2Fbootstrap-4.5.0.tgz"],
+ ["bootstrap", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.5.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbootstrap%2Fdownload%2Fbootstrap-4.5.2.tgz"],
["jquery", null],
["popper.js", null]
],
@@ -4180,12 +5183,12 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["camel-case", [
- ["npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamel-case%2Fdownload%2Fcamel-case-3.0.0.tgz", {
- "packageLocation": "./.yarn/cache/camel-case-npm-3.0.0-fe448a8de6-1cfcf1eb97.zip/node_modules/camel-case/",
+ ["npm:4.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamel-case%2Fdownload%2Fcamel-case-4.1.1.tgz", {
+ "packageLocation": "./.yarn/cache/camel-case-npm-4.1.1-12765494f7-c202f62a74.zip/node_modules/camel-case/",
"packageDependencies": [
- ["camel-case", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamel-case%2Fdownload%2Fcamel-case-3.0.0.tgz"],
- ["no-case", "npm:2.3.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fno-case%2Fdownload%2Fno-case-2.3.2.tgz"],
- ["upper-case", "npm:1.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fupper-case%2Fdownload%2Fupper-case-1.1.3.tgz"]
+ ["camel-case", "npm:4.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamel-case%2Fdownload%2Fcamel-case-4.1.1.tgz"],
+ ["pascal-case", "npm:3.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpascal-case%2Fdownload%2Fpascal-case-3.1.1.tgz"],
+ ["tslib", "npm:1.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftslib%2Fdownload%2Ftslib-1.13.0.tgz"]
],
"linkType": "HARD",
}]
@@ -4197,6 +5200,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["camelcase", "npm:5.3.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamelcase%2Fdownload%2Fcamelcase-5.3.1.tgz"]
],
"linkType": "HARD",
+ }],
+ ["npm:6.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamelcase%2Fdownload%2Fcamelcase-6.0.0.tgz", {
+ "packageLocation": "./.yarn/cache/camelcase-npm-6.0.0-eebcdeddbd-d92305180b.zip/node_modules/camelcase/",
+ "packageDependencies": [
+ ["camelcase", "npm:6.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamelcase%2Fdownload%2Fcamelcase-6.0.0.tgz"]
+ ],
+ "linkType": "HARD",
}]
]],
["caniuse-lite", [
@@ -4396,7 +5406,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["clean-webpack-plugin", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fclean-webpack-plugin%2Fdownload%2Fclean-webpack-plugin-3.0.0.tgz"],
["@types/webpack", "npm:4.41.21::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fwebpack%2Fdownload%2F%40types%2Fwebpack-4.41.21.tgz"],
["del", "npm:4.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdel%2Fdownload%2Fdel-4.1.1.tgz"],
- ["webpack", "npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz"]
+ ["webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"]
],
"packagePeers": [
"webpack"
@@ -4527,24 +5537,17 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["commander", [
- ["npm:2.17.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.17.1.tgz", {
- "packageLocation": "./.yarn/cache/commander-npm-2.17.1-c5dfdc987d-017ef909a7.zip/node_modules/commander/",
- "packageDependencies": [
- ["commander", "npm:2.17.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.17.1.tgz"]
- ],
- "linkType": "HARD",
- }],
- ["npm:2.19.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.19.0.tgz", {
- "packageLocation": "./.yarn/cache/commander-npm-2.19.0-4a8c4bd354-1a18c37b38.zip/node_modules/commander/",
+ ["npm:2.20.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.20.3.tgz", {
+ "packageLocation": "./.yarn/cache/commander-npm-2.20.3-ae9b12bcd9-b73428e97d.zip/node_modules/commander/",
"packageDependencies": [
- ["commander", "npm:2.19.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.19.0.tgz"]
+ ["commander", "npm:2.20.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.20.3.tgz"]
],
"linkType": "HARD",
}],
- ["npm:2.20.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.20.3.tgz", {
- "packageLocation": "./.yarn/cache/commander-npm-2.20.3-ae9b12bcd9-b73428e97d.zip/node_modules/commander/",
+ ["npm:4.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-4.1.1.tgz", {
+ "packageLocation": "./.yarn/cache/commander-npm-4.1.1-69c282739d-448585071b.zip/node_modules/commander/",
"packageDependencies": [
- ["commander", "npm:2.20.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.20.3.tgz"]
+ ["commander", "npm:4.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-4.1.1.tgz"]
],
"linkType": "HARD",
}]
@@ -4759,7 +5762,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["p-limit", "npm:3.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-limit%2Fdownload%2Fp-limit-3.0.2.tgz"],
["schema-utils", "npm:2.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fschema-utils%2Fdownload%2Fschema-utils-2.7.0.tgz"],
["serialize-javascript", "npm:4.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fserialize-javascript%2Fdownload%2Fserialize-javascript-4.0.0.tgz"],
- ["webpack", "npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz"],
+ ["webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"],
["webpack-sources", "npm:1.4.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-sources%2Fdownload%2Fwebpack-sources-1.4.3.tgz"]
],
"packagePeers": [
@@ -4976,24 +5979,24 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["css-loader", [
- ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-loader%2Fdownload%2Fcss-loader-3.6.0.tgz", {
- "packageLocation": "./.yarn/$$virtual/css-loader-virtual-6a5b7dede3/0/cache/css-loader-npm-3.6.0-86345a6b53-f916e1dc69.zip/node_modules/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", {
+ "packageLocation": "./.yarn/$$virtual/css-loader-virtual-217c7c2352/0/cache/css-loader-npm-4.2.1-093499999a-bd8188efac.zip/node_modules/css-loader/",
"packageDependencies": [
- ["css-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-loader%2Fdownload%2Fcss-loader-3.6.0.tgz"],
- ["camelcase", "npm:5.3.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamelcase%2Fdownload%2Fcamelcase-5.3.1.tgz"],
+ ["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"],
+ ["camelcase", "npm:6.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamelcase%2Fdownload%2Fcamelcase-6.0.0.tgz"],
["cssesc", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcssesc%2Fdownload%2Fcssesc-3.0.0.tgz"],
["icss-utils", "npm:4.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ficss-utils%2Fdownload%2Ficss-utils-4.1.1.tgz"],
- ["loader-utils", "npm:1.4.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-utils%2Fdownload%2Floader-utils-1.4.0.tgz"],
+ ["loader-utils", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-utils%2Fdownload%2Floader-utils-2.0.0.tgz"],
["normalize-path", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fnormalize-path%2Fdownload%2Fnormalize-path-3.0.0.tgz"],
["postcss", "npm:7.0.32::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss%2Fdownload%2Fpostcss-7.0.32.tgz"],
["postcss-modules-extract-imports", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-modules-extract-imports%2Fdownload%2Fpostcss-modules-extract-imports-2.0.0.tgz"],
- ["postcss-modules-local-by-default", "npm:3.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-modules-local-by-default%2Fdownload%2Fpostcss-modules-local-by-default-3.0.2.tgz"],
+ ["postcss-modules-local-by-default", "npm:3.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-modules-local-by-default%2Fdownload%2Fpostcss-modules-local-by-default-3.0.3.tgz"],
["postcss-modules-scope", "npm:2.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-modules-scope%2Fdownload%2Fpostcss-modules-scope-2.2.0.tgz"],
["postcss-modules-values", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-modules-values%2Fdownload%2Fpostcss-modules-values-3.0.0.tgz"],
["postcss-value-parser", "npm:4.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-value-parser%2Fdownload%2Fpostcss-value-parser-4.1.0.tgz"],
["schema-utils", "npm:2.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fschema-utils%2Fdownload%2Fschema-utils-2.7.0.tgz"],
- ["semver", "npm:6.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-6.3.0.tgz"],
- ["webpack", "npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz"]
+ ["semver", "npm:7.3.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-7.3.2.tgz"],
+ ["webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"]
],
"packagePeers": [
"webpack"
@@ -5074,6 +6077,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["csstype", "npm:2.6.11::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcsstype%2Fdownload%2Fcsstype-2.6.11.tgz"]
],
"linkType": "HARD",
+ }],
+ ["npm:3.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcsstype%2Fdownload%2Fcsstype-3.0.2.tgz", {
+ "packageLocation": "./.yarn/cache/csstype-npm-3.0.2-653341ad2a-acf2852a3c.zip/node_modules/csstype/",
+ "packageDependencies": [
+ ["csstype", "npm:3.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcsstype%2Fdownload%2Fcsstype-3.0.2.tgz"]
+ ],
+ "linkType": "HARD",
}]
]],
["cyclist", [
@@ -5530,6 +6540,17 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD",
}]
]],
+ ["dot-case", [
+ ["npm:3.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdot-case%2Fdownload%2Fdot-case-3.0.3.tgz", {
+ "packageLocation": "./.yarn/cache/dot-case-npm-3.0.3-54b8ad3b9a-31e5037039.zip/node_modules/dot-case/",
+ "packageDependencies": [
+ ["dot-case", "npm:3.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdot-case%2Fdownload%2Fdot-case-3.0.3.tgz"],
+ ["no-case", "npm:3.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fno-case%2Fdownload%2Fno-case-3.0.3.tgz"],
+ ["tslib", "npm:1.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftslib%2Fdownload%2Ftslib-1.13.0.tgz"]
+ ],
+ "linkType": "HARD",
+ }]
+ ]],
["duplexify", [
["npm:3.7.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fduplexify%2Fdownload%2Fduplexify-3.7.1.tgz", {
"packageLocation": "./.yarn/cache/duplexify-npm-3.7.1-64b25efcf2-9581cdb8f6.zip/node_modules/duplexify/",
@@ -5627,13 +6648,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["emojis-list", [
- ["npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Femojis-list%2Fdownload%2Femojis-list-2.1.0.tgz", {
- "packageLocation": "./.yarn/cache/emojis-list-npm-2.1.0-69329d1d27-09220b636c.zip/node_modules/emojis-list/",
- "packageDependencies": [
- ["emojis-list", "npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Femojis-list%2Fdownload%2Femojis-list-2.1.0.tgz"]
- ],
- "linkType": "HARD",
- }],
["npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Femojis-list%2Fdownload%2Femojis-list-3.0.0.tgz", {
"packageLocation": "./.yarn/cache/emojis-list-npm-3.0.0-54fce2c8ca-a79126b55b.zip/node_modules/emojis-list/",
"packageDependencies": [
@@ -5796,10 +6810,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["eslint", [
- ["npm:7.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.5.0.tgz", {
- "packageLocation": "./.yarn/cache/eslint-npm-7.5.0-587a6f90cb-5a65f133db.zip/node_modules/eslint/",
+ ["npm:7.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.7.0.tgz", {
+ "packageLocation": "./.yarn/cache/eslint-npm-7.7.0-a47135f486-6f47e20ec6.zip/node_modules/eslint/",
"packageDependencies": [
- ["eslint", "npm:7.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.5.0.tgz"],
+ ["eslint", "npm:7.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.7.0.tgz"],
["@babel/code-frame", "npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcode-frame%2Fdownload%2F%40babel%2Fcode-frame-7.10.4.tgz"],
["ajv", "npm:6.12.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv%2Fdownload%2Fajv-6.12.3.tgz"],
["chalk", "npm:4.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-4.1.0.tgz"],
@@ -5845,7 +6859,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./.yarn/$$virtual/eslint-config-prettier-virtual-671b2d82dd/0/cache/eslint-config-prettier-npm-6.11.0-032cc9f188-59efd906c7.zip/node_modules/eslint-config-prettier/",
"packageDependencies": [
["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", "npm:7.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.5.0.tgz"],
+ ["eslint", "npm:7.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.7.0.tgz"],
["get-stdin", "npm:6.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fget-stdin%2Fdownload%2Fget-stdin-6.0.0.tgz"]
],
"packagePeers": [
@@ -5859,8 +6873,8 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "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/",
"packageDependencies": [
["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", "npm:7.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.5.0.tgz"],
- ["prettier", "npm:2.0.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-2.0.5.tgz"],
+ ["eslint", "npm:7.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.7.0.tgz"],
+ ["prettier", "npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-2.1.0.tgz"],
["prettier-linter-helpers", "npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier-linter-helpers%2Fdownload%2Fprettier-linter-helpers-1.0.0.tgz"]
],
"packagePeers": [
@@ -5871,14 +6885,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["eslint-plugin-react", [
- ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.20.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-react%2Fdownload%2Feslint-plugin-react-7.20.3.tgz", {
- "packageLocation": "./.yarn/$$virtual/eslint-plugin-react-virtual-b26398b732/0/cache/eslint-plugin-react-npm-7.20.3-ea3ffb4ce9-00b1e5045e.zip/node_modules/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", {
+ "packageLocation": "./.yarn/$$virtual/eslint-plugin-react-virtual-90bf9cbb7a/0/cache/eslint-plugin-react-npm-7.20.6-74e425361b-e962f31c32.zip/node_modules/eslint-plugin-react/",
"packageDependencies": [
- ["eslint-plugin-react", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.20.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-react%2Fdownload%2Feslint-plugin-react-7.20.3.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"],
["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.flatmap", "npm:1.2.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray.prototype.flatmap%2Fdownload%2Farray.prototype.flatmap-1.2.3.tgz"],
["doctrine", "npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdoctrine%2Fdownload%2Fdoctrine-2.1.0.tgz"],
- ["eslint", "npm:7.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.5.0.tgz"],
+ ["eslint", "npm:7.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.7.0.tgz"],
["has", "npm:1.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas%2Fdownload%2Fhas-1.0.3.tgz"],
["jsx-ast-utils", "npm:2.4.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fjsx-ast-utils%2Fdownload%2Fjsx-ast-utils-2.4.1.tgz"],
["object.entries", "npm:1.1.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fobject.entries%2Fdownload%2Fobject.entries-1.1.2.tgz"],
@@ -5895,11 +6909,11 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["eslint-plugin-react-hooks", [
- ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.0.8::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-react-hooks%2Fdownload%2Feslint-plugin-react-hooks-4.0.8.tgz", {
- "packageLocation": "./.yarn/$$virtual/eslint-plugin-react-hooks-virtual-fd632072f6/0/cache/eslint-plugin-react-hooks-npm-4.0.8-096b822a4c-6e6ce44f1f.zip/node_modules/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", {
+ "packageLocation": "./.yarn/$$virtual/eslint-plugin-react-hooks-virtual-a08e2b8a64/0/cache/eslint-plugin-react-hooks-npm-4.1.0-95058b4277-7ef1a971b2.zip/node_modules/eslint-plugin-react-hooks/",
"packageDependencies": [
- ["eslint-plugin-react-hooks", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.0.8::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-react-hooks%2Fdownload%2Feslint-plugin-react-hooks-4.0.8.tgz"],
- ["eslint", "npm:7.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.5.0.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"],
+ ["eslint", "npm:7.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.7.0.tgz"]
],
"packagePeers": [
"eslint"
@@ -6326,7 +7340,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["file-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:6.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffile-loader%2Fdownload%2Ffile-loader-6.0.0.tgz"],
["loader-utils", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-utils%2Fdownload%2Floader-utils-2.0.0.tgz"],
["schema-utils", "npm:2.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fschema-utils%2Fdownload%2Fschema-utils-2.7.0.tgz"],
- ["webpack", "npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz"]
+ ["webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"]
],
"packagePeers": [
"webpack"
@@ -6476,6 +7490,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["follow-redirects", [
+ ["npm:1.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.13.0.tgz", {
+ "packageLocation": "./.yarn/cache/follow-redirects-npm-1.13.0-d909d3d20e-f220828d3f.zip/node_modules/follow-redirects/",
+ "packageDependencies": [
+ ["follow-redirects", "npm:1.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.13.0.tgz"]
+ ],
+ "linkType": "HARD",
+ }],
["npm:1.5.10::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.5.10.tgz", {
"packageLocation": "./.yarn/cache/follow-redirects-npm-1.5.10-336c353792-6e58e02c31.zip/node_modules/follow-redirects/",
"packageDependencies": [
@@ -7168,18 +8189,18 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD",
}]
]],
- ["html-minifier", [
- ["npm:3.5.21::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-minifier%2Fdownload%2Fhtml-minifier-3.5.21.tgz", {
- "packageLocation": "./.yarn/cache/html-minifier-npm-3.5.21-f8bb8662e1-c392d2128c.zip/node_modules/html-minifier/",
+ ["html-minifier-terser", [
+ ["npm:5.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-minifier-terser%2Fdownload%2Fhtml-minifier-terser-5.1.1.tgz", {
+ "packageLocation": "./.yarn/cache/html-minifier-terser-npm-5.1.1-904e8f6ed0-d05dea891f.zip/node_modules/html-minifier-terser/",
"packageDependencies": [
- ["html-minifier", "npm:3.5.21::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-minifier%2Fdownload%2Fhtml-minifier-3.5.21.tgz"],
- ["camel-case", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamel-case%2Fdownload%2Fcamel-case-3.0.0.tgz"],
+ ["html-minifier-terser", "npm:5.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-minifier-terser%2Fdownload%2Fhtml-minifier-terser-5.1.1.tgz"],
+ ["camel-case", "npm:4.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamel-case%2Fdownload%2Fcamel-case-4.1.1.tgz"],
["clean-css", "npm:4.2.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fclean-css%2Fdownload%2Fclean-css-4.2.3.tgz"],
- ["commander", "npm:2.17.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.17.1.tgz"],
+ ["commander", "npm:4.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-4.1.1.tgz"],
["he", "npm:1.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhe%2Fdownload%2Fhe-1.2.0.tgz"],
- ["param-case", "npm:2.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fparam-case%2Fdownload%2Fparam-case-2.1.1.tgz"],
+ ["param-case", "npm:3.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fparam-case%2Fdownload%2Fparam-case-3.0.3.tgz"],
["relateurl", "npm:0.2.7::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Frelateurl%2Fdownload%2Frelateurl-0.2.7.tgz"],
- ["uglify-js", "npm:3.4.10::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fuglify-js%2Fdownload%2Fuglify-js-3.4.10.tgz"]
+ ["terser", "npm:4.8.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser%2Fdownload%2Fterser-4.8.0.tgz"]
],
"linkType": "HARD",
}]
@@ -7195,18 +8216,20 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["html-webpack-plugin", [
- ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-webpack-plugin%2Fdownload%2Fhtml-webpack-plugin-3.2.0.tgz", {
- "packageLocation": "./.yarn/$$virtual/html-webpack-plugin-virtual-582ed630a9/0/cache/html-webpack-plugin-npm-3.2.0-8892662d8e-02dcb274a8.zip/node_modules/html-webpack-plugin/",
+ ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-webpack-plugin%2Fdownload%2Fhtml-webpack-plugin-4.3.0.tgz", {
+ "packageLocation": "./.yarn/$$virtual/html-webpack-plugin-virtual-15a3a0f996/0/cache/html-webpack-plugin-npm-4.3.0-295e66dc16-13c23547ac.zip/node_modules/html-webpack-plugin/",
"packageDependencies": [
- ["html-webpack-plugin", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-webpack-plugin%2Fdownload%2Fhtml-webpack-plugin-3.2.0.tgz"],
- ["html-minifier", "npm:3.5.21::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-minifier%2Fdownload%2Fhtml-minifier-3.5.21.tgz"],
- ["loader-utils", "npm:0.2.17::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-utils%2Fdownload%2Floader-utils-0.2.17.tgz"],
+ ["html-webpack-plugin", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-webpack-plugin%2Fdownload%2Fhtml-webpack-plugin-4.3.0.tgz"],
+ ["@types/html-minifier-terser", "npm:5.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fhtml-minifier-terser%2Fdownload%2F%40types%2Fhtml-minifier-terser-5.1.0.tgz"],
+ ["@types/tapable", "npm:1.0.6::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Ftapable%2Fdownload%2F%40types%2Ftapable-1.0.6.tgz"],
+ ["@types/webpack", "npm:4.41.21::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fwebpack%2Fdownload%2F%40types%2Fwebpack-4.41.21.tgz"],
+ ["html-minifier-terser", "npm:5.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-minifier-terser%2Fdownload%2Fhtml-minifier-terser-5.1.1.tgz"],
+ ["loader-utils", "npm:1.4.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-utils%2Fdownload%2Floader-utils-1.4.0.tgz"],
["lodash", "npm:4.17.19::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.19.tgz"],
["pretty-error", "npm:2.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpretty-error%2Fdownload%2Fpretty-error-2.1.1.tgz"],
["tapable", "npm:1.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftapable%2Fdownload%2Ftapable-1.1.3.tgz"],
- ["toposort", "npm:1.0.7::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftoposort%2Fdownload%2Ftoposort-1.0.7.tgz"],
["util.promisify", "npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Futil.promisify%2Fdownload%2Futil.promisify-1.0.0.tgz"],
- ["webpack", "npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz"]
+ ["webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"]
],
"packagePeers": [
"webpack"
@@ -7370,20 +8393,20 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["i18next", [
- ["npm:19.6.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next%2Fdownload%2Fi18next-19.6.2.tgz", {
- "packageLocation": "./.yarn/cache/i18next-npm-19.6.2-e0c8a24aa8-50bef70b0e.zip/node_modules/i18next/",
+ ["npm:19.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next%2Fdownload%2Fi18next-19.7.0.tgz", {
+ "packageLocation": "./.yarn/cache/i18next-npm-19.7.0-a8993e2c4d-7f6fa6576c.zip/node_modules/i18next/",
"packageDependencies": [
- ["i18next", "npm:19.6.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next%2Fdownload%2Fi18next-19.6.2.tgz"],
+ ["i18next", "npm:19.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next%2Fdownload%2Fi18next-19.7.0.tgz"],
["@babel/runtime", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fruntime%2Fdownload%2F%40babel%2Fruntime-7.10.5.tgz"]
],
"linkType": "HARD",
}]
]],
["i18next-browser-languagedetector", [
- ["npm:5.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next-browser-languagedetector%2Fdownload%2Fi18next-browser-languagedetector-5.0.0.tgz", {
- "packageLocation": "./.yarn/cache/i18next-browser-languagedetector-npm-5.0.0-3775f73394-0304f0469d.zip/node_modules/i18next-browser-languagedetector/",
+ ["npm:6.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next-browser-languagedetector%2Fdownload%2Fi18next-browser-languagedetector-6.0.1.tgz", {
+ "packageLocation": "./.yarn/cache/i18next-browser-languagedetector-npm-6.0.1-9d0cfe54e7-760bc83f3b.zip/node_modules/i18next-browser-languagedetector/",
"packageDependencies": [
- ["i18next-browser-languagedetector", "npm:5.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next-browser-languagedetector%2Fdownload%2Fi18next-browser-languagedetector-5.0.0.tgz"],
+ ["i18next-browser-languagedetector", "npm:6.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next-browser-languagedetector%2Fdownload%2Fi18next-browser-languagedetector-6.0.1.tgz"],
["@babel/runtime", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fruntime%2Fdownload%2F%40babel%2Fruntime-7.10.5.tgz"]
],
"linkType": "HARD",
@@ -8218,13 +9241,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["json5", [
- ["npm:0.5.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson5%2Fdownload%2Fjson5-0.5.1.tgz", {
- "packageLocation": "./.yarn/cache/json5-npm-0.5.1-8adaf551a7-002ce9e56c.zip/node_modules/json5/",
- "packageDependencies": [
- ["json5", "npm:0.5.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson5%2Fdownload%2Fjson5-0.5.1.tgz"]
- ],
- "linkType": "HARD",
- }],
["npm:1.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson5%2Fdownload%2Fjson5-1.0.1.tgz", {
"packageLocation": "./.yarn/cache/json5-npm-1.0.1-3cf74843da-df41624f9f.zip/node_modules/json5/",
"packageDependencies": [
@@ -8386,17 +9402,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["loader-utils", [
- ["npm:0.2.17::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-utils%2Fdownload%2Floader-utils-0.2.17.tgz", {
- "packageLocation": "./.yarn/cache/loader-utils-npm-0.2.17-07496ea16b-aae13ef9f1.zip/node_modules/loader-utils/",
- "packageDependencies": [
- ["loader-utils", "npm:0.2.17::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-utils%2Fdownload%2Floader-utils-0.2.17.tgz"],
- ["big.js", "npm:3.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbig.js%2Fdownload%2Fbig.js-3.2.0.tgz"],
- ["emojis-list", "npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Femojis-list%2Fdownload%2Femojis-list-2.1.0.tgz"],
- ["json5", "npm:0.5.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson5%2Fdownload%2Fjson5-0.5.1.tgz"],
- ["object-assign", "npm:4.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fobject-assign%2Fdownload%2Fobject-assign-4.1.1.tgz"]
- ],
- "linkType": "HARD",
- }],
["npm:1.4.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-utils%2Fdownload%2Floader-utils-1.4.0.tgz", {
"packageLocation": "./.yarn/cache/loader-utils-npm-1.4.0-24f50da64c-9fd690e57a.zip/node_modules/loader-utils/",
"packageDependencies": [
@@ -8419,10 +9424,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["localforage", [
- ["npm:1.7.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocalforage%2Fdownload%2Flocalforage-1.7.4.tgz", {
- "packageLocation": "./.yarn/cache/localforage-npm-1.7.4-e6e6050858-81815ccb02.zip/node_modules/localforage/",
+ ["npm:1.9.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocalforage%2Fdownload%2Flocalforage-1.9.0.tgz", {
+ "packageLocation": "./.yarn/cache/localforage-npm-1.9.0-5007685607-0645f5ec6f.zip/node_modules/localforage/",
"packageDependencies": [
- ["localforage", "npm:1.7.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocalforage%2Fdownload%2Flocalforage-1.7.4.tgz"],
+ ["localforage", "npm:1.9.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocalforage%2Fdownload%2Flocalforage-1.9.0.tgz"],
["lie", "npm:3.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flie%2Fdownload%2Flie-3.1.1.tgz"]
],
"linkType": "HARD",
@@ -8454,6 +9459,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["lodash", "npm:4.17.19::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.19.tgz"]
],
"linkType": "HARD",
+ }],
+ ["npm:4.17.20::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.20.tgz", {
+ "packageLocation": "./.yarn/cache/lodash-npm-4.17.20-3d0d643e5a-c62101d250.zip/node_modules/lodash/",
+ "packageDependencies": [
+ ["lodash", "npm:4.17.20::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.20.tgz"]
+ ],
+ "linkType": "HARD",
}]
]],
["lodash._reinterpolate", [
@@ -8516,10 +9528,11 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["lower-case", [
- ["npm:1.1.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flower-case%2Fdownload%2Flower-case-1.1.4.tgz", {
- "packageLocation": "./.yarn/cache/lower-case-npm-1.1.4-2463967906-8150698ed1.zip/node_modules/lower-case/",
+ ["npm:2.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flower-case%2Fdownload%2Flower-case-2.0.1.tgz", {
+ "packageLocation": "./.yarn/cache/lower-case-npm-2.0.1-5e77048bd0-52a55327ea.zip/node_modules/lower-case/",
"packageDependencies": [
- ["lower-case", "npm:1.1.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flower-case%2Fdownload%2Flower-case-1.1.4.tgz"]
+ ["lower-case", "npm:2.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flower-case%2Fdownload%2Flower-case-2.0.1.tgz"],
+ ["tslib", "npm:1.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftslib%2Fdownload%2Ftslib-1.13.0.tgz"]
],
"linkType": "HARD",
}]
@@ -8814,7 +9827,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["loader-utils", "npm:1.4.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-utils%2Fdownload%2Floader-utils-1.4.0.tgz"],
["normalize-url", "npm:1.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fnormalize-url%2Fdownload%2Fnormalize-url-1.9.1.tgz"],
["schema-utils", "npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fschema-utils%2Fdownload%2Fschema-utils-1.0.0.tgz"],
- ["webpack", "npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz"],
+ ["webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"],
["webpack-sources", "npm:1.4.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-sources%2Fdownload%2Fwebpack-sources-1.4.3.tgz"]
],
"packagePeers": [
@@ -9100,11 +10113,12 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["no-case", [
- ["npm:2.3.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fno-case%2Fdownload%2Fno-case-2.3.2.tgz", {
- "packageLocation": "./.yarn/cache/no-case-npm-2.3.2-9b0e64173c-b4206dd12c.zip/node_modules/no-case/",
+ ["npm:3.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fno-case%2Fdownload%2Fno-case-3.0.3.tgz", {
+ "packageLocation": "./.yarn/cache/no-case-npm-3.0.3-8458d9e79f-619e0bd00a.zip/node_modules/no-case/",
"packageDependencies": [
- ["no-case", "npm:2.3.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fno-case%2Fdownload%2Fno-case-2.3.2.tgz"],
- ["lower-case", "npm:1.1.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flower-case%2Fdownload%2Flower-case-1.1.4.tgz"]
+ ["no-case", "npm:3.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fno-case%2Fdownload%2Fno-case-3.0.3.tgz"],
+ ["lower-case", "npm:2.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flower-case%2Fdownload%2Flower-case-2.0.1.tgz"],
+ ["tslib", "npm:1.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftslib%2Fdownload%2Ftslib-1.13.0.tgz"]
],
"linkType": "HARD",
}]
@@ -9685,11 +10699,12 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["param-case", [
- ["npm:2.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fparam-case%2Fdownload%2Fparam-case-2.1.1.tgz", {
- "packageLocation": "./.yarn/cache/param-case-npm-2.1.1-302a2fde31-2983386706.zip/node_modules/param-case/",
+ ["npm:3.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fparam-case%2Fdownload%2Fparam-case-3.0.3.tgz", {
+ "packageLocation": "./.yarn/cache/param-case-npm-3.0.3-84b1b78d85-ef57facfaf.zip/node_modules/param-case/",
"packageDependencies": [
- ["param-case", "npm:2.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fparam-case%2Fdownload%2Fparam-case-2.1.1.tgz"],
- ["no-case", "npm:2.3.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fno-case%2Fdownload%2Fno-case-2.3.2.tgz"]
+ ["param-case", "npm:3.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fparam-case%2Fdownload%2Fparam-case-3.0.3.tgz"],
+ ["dot-case", "npm:3.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdot-case%2Fdownload%2Fdot-case-3.0.3.tgz"],
+ ["tslib", "npm:1.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftslib%2Fdownload%2Ftslib-1.13.0.tgz"]
],
"linkType": "HARD",
}]
@@ -9748,6 +10763,17 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD",
}]
]],
+ ["pascal-case", [
+ ["npm:3.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpascal-case%2Fdownload%2Fpascal-case-3.1.1.tgz", {
+ "packageLocation": "./.yarn/cache/pascal-case-npm-3.1.1-ffa0435e29-56f66aea7f.zip/node_modules/pascal-case/",
+ "packageDependencies": [
+ ["pascal-case", "npm:3.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpascal-case%2Fdownload%2Fpascal-case-3.1.1.tgz"],
+ ["no-case", "npm:3.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fno-case%2Fdownload%2Fno-case-3.0.3.tgz"],
+ ["tslib", "npm:1.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftslib%2Fdownload%2Ftslib-1.13.0.tgz"]
+ ],
+ "linkType": "HARD",
+ }]
+ ]],
["pascalcase", [
["npm:0.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpascalcase%2Fdownload%2Fpascalcase-0.1.1.tgz", {
"packageLocation": "./.yarn/cache/pascalcase-npm-0.1.1-9044796ab3-268a9dbf9c.zip/node_modules/pascalcase/",
@@ -10277,10 +11303,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["postcss-modules-local-by-default", [
- ["npm:3.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-modules-local-by-default%2Fdownload%2Fpostcss-modules-local-by-default-3.0.2.tgz", {
- "packageLocation": "./.yarn/cache/postcss-modules-local-by-default-npm-3.0.2-b77c48e0b6-32d04c364f.zip/node_modules/postcss-modules-local-by-default/",
+ ["npm:3.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-modules-local-by-default%2Fdownload%2Fpostcss-modules-local-by-default-3.0.3.tgz", {
+ "packageLocation": "./.yarn/cache/postcss-modules-local-by-default-npm-3.0.3-9ba3761380-6d34b3b1dc.zip/node_modules/postcss-modules-local-by-default/",
"packageDependencies": [
- ["postcss-modules-local-by-default", "npm:3.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-modules-local-by-default%2Fdownload%2Fpostcss-modules-local-by-default-3.0.2.tgz"],
+ ["postcss-modules-local-by-default", "npm:3.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-modules-local-by-default%2Fdownload%2Fpostcss-modules-local-by-default-3.0.3.tgz"],
["icss-utils", "npm:4.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ficss-utils%2Fdownload%2Ficss-utils-4.1.1.tgz"],
["postcss", "npm:7.0.32::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss%2Fdownload%2Fpostcss-7.0.32.tgz"],
["postcss-selector-parser", "npm:6.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-selector-parser%2Fdownload%2Fpostcss-selector-parser-6.0.2.tgz"],
@@ -10503,10 +11529,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["prettier", [
- ["npm:2.0.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-2.0.5.tgz", {
- "packageLocation": "./.yarn/cache/prettier-npm-2.0.5-c6a34cbe68-d249d89361.zip/node_modules/prettier/",
+ ["npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-2.1.0.tgz", {
+ "packageLocation": "./.yarn/cache/prettier-npm-2.1.0-55e4625555-f955d380d2.zip/node_modules/prettier/",
"packageDependencies": [
- ["prettier", "npm:2.0.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-2.0.5.tgz"]
+ ["prettier", "npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-2.1.0.tgz"]
],
"linkType": "HARD",
}]
@@ -10879,7 +11905,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./.yarn/$$virtual/react-hot-loader-virtual-03e83e357e/0/cache/react-hot-loader-npm-4.12.21-5b5b8661aa-371deabe49.zip/node_modules/react-hot-loader/",
"packageDependencies": [
["react-hot-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.12.21::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-hot-loader%2Fdownload%2Freact-hot-loader-4.12.21.tgz"],
- ["@types/react", "npm:16.9.43::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact%2Fdownload%2F%40types%2Freact-16.9.43.tgz"],
+ ["@types/react", "npm:16.9.46::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact%2Fdownload%2F%40types%2Freact-16.9.46.tgz"],
["fast-levenshtein", "npm:2.0.6::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-levenshtein%2Fdownload%2Ffast-levenshtein-2.0.6.tgz"],
["global", "npm:4.4.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fglobal%2Fdownload%2Fglobal-4.4.0.tgz"],
["hoist-non-react-statics", "npm:3.3.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhoist-non-react-statics%2Fdownload%2Fhoist-non-react-statics-3.3.2.tgz"],
@@ -10900,13 +11926,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["react-i18next", [
- ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:11.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-i18next%2Fdownload%2Freact-i18next-11.7.0.tgz", {
- "packageLocation": "./.yarn/$$virtual/react-i18next-virtual-1f01c08381/0/cache/react-i18next-npm-11.7.0-aa42e512bb-3559428ecf.zip/node_modules/react-i18next/",
+ ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:11.7.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-i18next%2Fdownload%2Freact-i18next-11.7.1.tgz", {
+ "packageLocation": "./.yarn/$$virtual/react-i18next-virtual-b9c7e9253e/0/cache/react-i18next-npm-11.7.1-9665be9025-fc62ae35c3.zip/node_modules/react-i18next/",
"packageDependencies": [
- ["react-i18next", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:11.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-i18next%2Fdownload%2Freact-i18next-11.7.0.tgz"],
+ ["react-i18next", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:11.7.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-i18next%2Fdownload%2Freact-i18next-11.7.1.tgz"],
["@babel/runtime", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fruntime%2Fdownload%2F%40babel%2Fruntime-7.10.5.tgz"],
["html-parse-stringify2", "npm:2.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-parse-stringify2%2Fdownload%2Fhtml-parse-stringify2-2.0.1.tgz"],
- ["i18next", "npm:19.6.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next%2Fdownload%2Fi18next-19.6.2.tgz"],
+ ["i18next", "npm:19.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next%2Fdownload%2Fi18next-19.7.0.tgz"],
["react", "npm:16.13.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact%2Fdownload%2Freact-16.13.1.tgz"]
],
"packagePeers": [
@@ -11147,6 +12173,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["regenerator-runtime", "npm:0.13.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.13.5.tgz"]
],
"linkType": "HARD",
+ }],
+ ["npm:0.13.7::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.13.7.tgz", {
+ "packageLocation": "./.yarn/cache/regenerator-runtime-npm-0.13.7-2b1c616ba8-6ef567c662.zip/node_modules/regenerator-runtime/",
+ "packageDependencies": [
+ ["regenerator-runtime", "npm:0.13.7::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.13.7.tgz"]
+ ],
+ "linkType": "HARD",
}]
]],
["regenerator-transform", [
@@ -11555,10 +12588,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["rxjs", [
- ["npm:6.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Frxjs%2Fdownload%2Frxjs-6.6.0.tgz", {
- "packageLocation": "./.yarn/cache/rxjs-npm-6.6.0-79734bd415-32d733487c.zip/node_modules/rxjs/",
+ ["npm:6.6.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Frxjs%2Fdownload%2Frxjs-6.6.2.tgz", {
+ "packageLocation": "./.yarn/cache/rxjs-npm-6.6.2-286227e461-9b16cd3609.zip/node_modules/rxjs/",
"packageDependencies": [
- ["rxjs", "npm:6.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Frxjs%2Fdownload%2Frxjs-6.6.0.tgz"],
+ ["rxjs", "npm:6.6.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Frxjs%2Fdownload%2Frxjs-6.6.2.tgz"],
["tslib", "npm:1.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftslib%2Fdownload%2Ftslib-1.13.0.tgz"]
],
"linkType": "HARD",
@@ -11610,10 +12643,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["sass-loader", [
- ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:9.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsass-loader%2Fdownload%2Fsass-loader-9.0.2.tgz", {
- "packageLocation": "./.yarn/$$virtual/sass-loader-virtual-028c1fd14b/0/cache/sass-loader-npm-9.0.2-a89ff6ae33-4a27190349.zip/node_modules/sass-loader/",
+ ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:9.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsass-loader%2Fdownload%2Fsass-loader-9.0.3.tgz", {
+ "packageLocation": "./.yarn/$$virtual/sass-loader-virtual-b3384a0ffc/0/cache/sass-loader-npm-9.0.3-681753a244-5ce94bb670.zip/node_modules/sass-loader/",
"packageDependencies": [
- ["sass-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:9.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsass-loader%2Fdownload%2Fsass-loader-9.0.2.tgz"],
+ ["sass-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:9.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsass-loader%2Fdownload%2Fsass-loader-9.0.3.tgz"],
["fibers", null],
["klona", "npm:1.1.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fklona%2Fdownload%2Fklona-1.1.2.tgz"],
["loader-utils", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-utils%2Fdownload%2Floader-utils-2.0.0.tgz"],
@@ -11622,7 +12655,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["sass", "npm:1.26.10::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsass%2Fdownload%2Fsass-1.26.10.tgz"],
["schema-utils", "npm:2.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fschema-utils%2Fdownload%2Fschema-utils-2.7.0.tgz"],
["semver", "npm:7.3.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-7.3.2.tgz"],
- ["webpack", "npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz"]
+ ["webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"]
],
"packagePeers": [
"fibers",
@@ -12442,7 +13475,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["style-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:1.2.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fstyle-loader%2Fdownload%2Fstyle-loader-1.2.1.tgz"],
["loader-utils", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-utils%2Fdownload%2Floader-utils-2.0.0.tgz"],
["schema-utils", "npm:2.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fschema-utils%2Fdownload%2Fschema-utils-2.7.0.tgz"],
- ["webpack", "npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz"]
+ ["webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"]
],
"packagePeers": [
"webpack"
@@ -12568,10 +13601,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["terser-webpack-plugin", [
- ["virtual:06b502aafb84fcb61ef20bc57866555a7ce12e440462e300076735b608de2314dcb1fba9be6fa905fe744f9fb2b01b724fa5950152e80298429550725f755eab#npm:1.4.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser-webpack-plugin%2Fdownload%2Fterser-webpack-plugin-1.4.4.tgz", {
- "packageLocation": "./.yarn/$$virtual/terser-webpack-plugin-virtual-4b0521aeaf/0/cache/terser-webpack-plugin-npm-1.4.4-8e387c760c-51f918c648.zip/node_modules/terser-webpack-plugin/",
+ ["virtual:6430e17b2d0921d17a377f23f4a38fbda5d3da214d48b3ff0c374170f2ef2aaa9c21cce668fadeda53f3fbee00682b7aa1e684eb5ddddd5f4cd69290644b4773#npm:1.4.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser-webpack-plugin%2Fdownload%2Fterser-webpack-plugin-1.4.4.tgz", {
+ "packageLocation": "./.yarn/$$virtual/terser-webpack-plugin-virtual-8cb2deb0a3/0/cache/terser-webpack-plugin-npm-1.4.4-8e387c760c-51f918c648.zip/node_modules/terser-webpack-plugin/",
"packageDependencies": [
- ["terser-webpack-plugin", "virtual:06b502aafb84fcb61ef20bc57866555a7ce12e440462e300076735b608de2314dcb1fba9be6fa905fe744f9fb2b01b724fa5950152e80298429550725f755eab#npm:1.4.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser-webpack-plugin%2Fdownload%2Fterser-webpack-plugin-1.4.4.tgz"],
+ ["terser-webpack-plugin", "virtual:6430e17b2d0921d17a377f23f4a38fbda5d3da214d48b3ff0c374170f2ef2aaa9c21cce668fadeda53f3fbee00682b7aa1e684eb5ddddd5f4cd69290644b4773#npm:1.4.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser-webpack-plugin%2Fdownload%2Fterser-webpack-plugin-1.4.4.tgz"],
["cacache", "npm:12.0.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcacache%2Fdownload%2Fcacache-12.0.4.tgz"],
["find-cache-dir", "npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-cache-dir%2Fdownload%2Ffind-cache-dir-2.1.0.tgz"],
["is-wsl", "npm:1.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-wsl%2Fdownload%2Fis-wsl-1.1.0.tgz"],
@@ -12579,7 +13612,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["serialize-javascript", "npm:3.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fserialize-javascript%2Fdownload%2Fserialize-javascript-3.1.0.tgz"],
["source-map", "npm:0.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.6.1.tgz"],
["terser", "npm:4.8.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser%2Fdownload%2Fterser-4.8.0.tgz"],
- ["webpack", "npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz"],
+ ["webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"],
["webpack-sources", "npm:1.4.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-sources%2Fdownload%2Fwebpack-sources-1.4.3.tgz"],
["worker-farm", "npm:1.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fworker-farm%2Fdownload%2Fworker-farm-1.7.0.tgz"]
],
@@ -12623,35 +13656,35 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./",
"packageDependencies": [
["timeline", "workspace:."],
- ["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
+ ["@babel/core", "npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"],
["@babel/plugin-proposal-class-properties", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-class-properties%2Fdownload%2F%40babel%2Fplugin-proposal-class-properties-7.10.4.tgz"],
["@babel/plugin-proposal-decorators", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-decorators%2Fdownload%2F%40babel%2Fplugin-proposal-decorators-7.10.5.tgz"],
["@babel/plugin-proposal-nullish-coalescing-operator", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator%2Fdownload%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator-7.10.4.tgz"],
- ["@babel/plugin-proposal-optional-chaining", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-chaining%2Fdownload%2F%40babel%2Fplugin-proposal-optional-chaining-7.10.4.tgz"],
+ ["@babel/plugin-proposal-optional-chaining", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-chaining%2Fdownload%2F%40babel%2Fplugin-proposal-optional-chaining-7.11.0.tgz"],
["@babel/plugin-syntax-dynamic-import", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-dynamic-import%2Fdownload%2F%40babel%2Fplugin-syntax-dynamic-import-7.8.3.tgz"],
- ["@babel/preset-env", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-env%2Fdownload%2F%40babel%2Fpreset-env-7.10.4.tgz"],
+ ["@babel/preset-env", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-env%2Fdownload%2F%40babel%2Fpreset-env-7.11.0.tgz"],
["@babel/preset-react", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-react%2Fdownload%2F%40babel%2Fpreset-react-7.10.4.tgz"],
["@babel/preset-typescript", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-typescript%2Fdownload%2F%40babel%2Fpreset-typescript-7.10.4.tgz"],
["@hot-loader/react-dom", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:16.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40hot-loader%2Freact-dom%2Fdownload%2F%40hot-loader%2Freact-dom-16.13.0.tgz"],
["@types/classnames", "npm:2.2.10::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fclassnames%2Fdownload%2F%40types%2Fclassnames-2.2.10.tgz"],
["@types/crypto-js", "npm:3.1.47::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fcrypto-js%2Fdownload%2F%40types%2Fcrypto-js-3.1.47.tgz"],
- ["@types/lodash", "npm:4.14.157::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Flodash%2Fdownload%2F%40types%2Flodash-4.14.157.tgz"],
- ["@types/node", "npm:14.0.23::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-14.0.23.tgz"],
- ["@types/react", "npm:16.9.43::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact%2Fdownload%2F%40types%2Freact-16.9.43.tgz"],
+ ["@types/lodash", "npm:4.14.159::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Flodash%2Fdownload%2F%40types%2Flodash-4.14.159.tgz"],
+ ["@types/node", "npm:14.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-14.6.0.tgz"],
+ ["@types/react", "npm:16.9.46::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact%2Fdownload%2F%40types%2Freact-16.9.46.tgz"],
["@types/react-dom", "npm:16.9.8::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact-dom%2Fdownload%2F%40types%2Freact-dom-16.9.8.tgz"],
["@types/react-responsive", "npm:8.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact-responsive%2Fdownload%2F%40types%2Freact-responsive-8.0.2.tgz"],
["@types/react-router", "npm:5.1.8::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact-router%2Fdownload%2F%40types%2Freact-router-5.1.8.tgz"],
["@types/react-router-dom", "npm:5.1.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact-router-dom%2Fdownload%2F%40types%2Freact-router-dom-5.1.5.tgz"],
- ["@types/reactstrap", "npm:8.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freactstrap%2Fdownload%2F%40types%2Freactstrap-8.5.0.tgz"],
+ ["@types/reactstrap", "npm:8.5.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freactstrap%2Fdownload%2F%40types%2Freactstrap-8.5.1.tgz"],
["@types/webpack-env", "npm:1.15.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fwebpack-env%2Fdownload%2F%40types%2Fwebpack-env-1.15.2.tgz"],
["@types/xregexp", "npm:4.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fxregexp%2Fdownload%2F%40types%2Fxregexp-4.3.0.tgz"],
- ["@typescript-eslint/eslint-plugin", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Feslint-plugin%2Fdownload%2F%40typescript-eslint%2Feslint-plugin-3.6.1.tgz"],
- ["@typescript-eslint/parser", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fparser%2Fdownload%2F%40typescript-eslint%2Fparser-3.6.1.tgz"],
+ ["@typescript-eslint/eslint-plugin", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Feslint-plugin%2Fdownload%2F%40typescript-eslint%2Feslint-plugin-3.9.1.tgz"],
+ ["@typescript-eslint/parser", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fparser%2Fdownload%2F%40typescript-eslint%2Fparser-3.9.1.tgz"],
["@yarnpkg/pnpify", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40yarnpkg%2Fpnpify%2Fdownload%2F%40yarnpkg%2Fpnpify-2.1.0.tgz"],
- ["axios", "npm:0.19.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.19.2.tgz"],
+ ["axios", "npm:0.20.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.20.0.tgz"],
["babel-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:8.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-loader%2Fdownload%2Fbabel-loader-8.1.0.tgz"],
["babel-plugin-transform-builtin-extend", "npm:1.1.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-plugin-transform-builtin-extend%2Fdownload%2Fbabel-plugin-transform-builtin-extend-1.1.2.tgz"],
- ["bootstrap", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbootstrap%2Fdownload%2Fbootstrap-4.5.0.tgz"],
+ ["bootstrap", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.5.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbootstrap%2Fdownload%2Fbootstrap-4.5.2.tgz"],
["bootstrap-icons", "npm:1.0.0-alpha5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbootstrap-icons%2Fdownload%2Fbootstrap-icons-1.0.0-alpha5.tgz"],
["classnames", "npm:2.2.6::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fclassnames%2Fdownload%2Fclassnames-2.2.6.tgz"],
["clean-webpack-plugin", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fclean-webpack-plugin%2Fdownload%2Fclean-webpack-plugin-3.0.0.tgz"],
@@ -12659,43 +13692,43 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["copy-webpack-plugin", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:6.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcopy-webpack-plugin%2Fdownload%2Fcopy-webpack-plugin-6.0.3.tgz"],
["core-js", "npm:3.6.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js%2Fdownload%2Fcore-js-3.6.5.tgz"],
["crypto-js", "npm:4.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcrypto-js%2Fdownload%2Fcrypto-js-4.0.0.tgz"],
- ["css-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-loader%2Fdownload%2Fcss-loader-3.6.0.tgz"],
- ["eslint", "npm:7.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.5.0.tgz"],
+ ["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-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.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-react%2Fdownload%2Feslint-plugin-react-7.20.3.tgz"],
- ["eslint-plugin-react-hooks", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.0.8::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-react-hooks%2Fdownload%2Feslint-plugin-react-hooks-4.0.8.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"],
["file-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:6.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffile-loader%2Fdownload%2Ffile-loader-6.0.0.tgz"],
- ["html-webpack-plugin", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-webpack-plugin%2Fdownload%2Fhtml-webpack-plugin-3.2.0.tgz"],
+ ["html-webpack-plugin", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-webpack-plugin%2Fdownload%2Fhtml-webpack-plugin-4.3.0.tgz"],
["http-server", "npm:0.12.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-server%2Fdownload%2Fhttp-server-0.12.3.tgz"],
- ["i18next", "npm:19.6.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next%2Fdownload%2Fi18next-19.6.2.tgz"],
- ["i18next-browser-languagedetector", "npm:5.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next-browser-languagedetector%2Fdownload%2Fi18next-browser-languagedetector-5.0.0.tgz"],
- ["localforage", "npm:1.7.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocalforage%2Fdownload%2Flocalforage-1.7.4.tgz"],
- ["lodash", "npm:4.17.19::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.19.tgz"],
+ ["i18next", "npm:19.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next%2Fdownload%2Fi18next-19.7.0.tgz"],
+ ["i18next-browser-languagedetector", "npm:6.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next-browser-languagedetector%2Fdownload%2Fi18next-browser-languagedetector-6.0.1.tgz"],
+ ["localforage", "npm:1.9.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocalforage%2Fdownload%2Flocalforage-1.9.0.tgz"],
+ ["lodash", "npm:4.17.20::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.20.tgz"],
["mini-css-extract-plugin", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:0.10.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fmini-css-extract-plugin%2Fdownload%2Fmini-css-extract-plugin-0.10.0.tgz"],
["pepjs", "npm:0.5.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpepjs%2Fdownload%2Fpepjs-0.5.2.tgz"],
["pnp-webpack-plugin", "npm:1.6.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpnp-webpack-plugin%2Fdownload%2Fpnp-webpack-plugin-1.6.4.tgz"],
["postcss-loader", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-loader%2Fdownload%2Fpostcss-loader-3.0.0.tgz"],
["postcss-preset-env", "npm:6.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-preset-env%2Fdownload%2Fpostcss-preset-env-6.7.0.tgz"],
- ["prettier", "npm:2.0.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-2.0.5.tgz"],
+ ["prettier", "npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-2.1.0.tgz"],
["react", "npm:16.13.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact%2Fdownload%2Freact-16.13.1.tgz"],
["react-dom", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:16.13.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-dom%2Fdownload%2Freact-dom-16.13.1.tgz"],
["react-hot-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.12.21::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-hot-loader%2Fdownload%2Freact-hot-loader-4.12.21.tgz"],
- ["react-i18next", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:11.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-i18next%2Fdownload%2Freact-i18next-11.7.0.tgz"],
+ ["react-i18next", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:11.7.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-i18next%2Fdownload%2Freact-i18next-11.7.1.tgz"],
["react-inlinesvg", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-inlinesvg%2Fdownload%2Freact-inlinesvg-2.0.0.tgz"],
["react-responsive", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:8.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-responsive%2Fdownload%2Freact-responsive-8.1.0.tgz"],
["react-router", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:5.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-router%2Fdownload%2Freact-router-5.2.0.tgz"],
["react-router-dom", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:5.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-router-dom%2Fdownload%2Freact-router-dom-5.2.0.tgz"],
["reactstrap", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:8.5.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freactstrap%2Fdownload%2Freactstrap-8.5.1.tgz"],
- ["regenerator-runtime", "npm:0.13.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.13.5.tgz"],
- ["rxjs", "npm:6.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Frxjs%2Fdownload%2Frxjs-6.6.0.tgz"],
+ ["regenerator-runtime", "npm:0.13.7::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.13.7.tgz"],
+ ["rxjs", "npm:6.6.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Frxjs%2Fdownload%2Frxjs-6.6.2.tgz"],
["sass", "npm:1.26.10::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsass%2Fdownload%2Fsass-1.26.10.tgz"],
- ["sass-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:9.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsass-loader%2Fdownload%2Fsass-loader-9.0.2.tgz"],
+ ["sass-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:9.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsass-loader%2Fdownload%2Fsass-loader-9.0.3.tgz"],
["style-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:1.2.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fstyle-loader%2Fdownload%2Fstyle-loader-1.2.1.tgz"],
- ["ts-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:8.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fts-loader%2Fdownload%2Fts-loader-8.0.1.tgz"],
- ["typescript", "patch:typescript@npm%3A3.9.7%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-3.9.7.tgz#builtin<compat/typescript>::version=3.9.7&hash=5b02a2"],
+ ["ts-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:8.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fts-loader%2Fdownload%2Fts-loader-8.0.3.tgz"],
+ ["typescript", "patch:typescript@npm%3A4.0.2%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-4.0.2.tgz#builtin<compat/typescript>::version=4.0.2&hash=5b02a2"],
["url-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Furl-loader%2Fdownload%2Furl-loader-4.1.0.tgz"],
- ["webpack", "npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz"],
+ ["webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"],
["webpack-chain", "npm:6.5.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-chain%2Fdownload%2Fwebpack-chain-6.5.1.tgz"],
["webpack-cli", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.3.12::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-cli%2Fdownload%2Fwebpack-cli-3.3.12.tgz"],
["webpack-dev-server", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-dev-server%2Fdownload%2Fwebpack-dev-server-3.11.0.tgz"],
@@ -12813,15 +13846,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD",
}]
]],
- ["toposort", [
- ["npm:1.0.7::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftoposort%2Fdownload%2Ftoposort-1.0.7.tgz", {
- "packageLocation": "./.yarn/cache/toposort-npm-1.0.7-413d1cd275-32544ffadb.zip/node_modules/toposort/",
- "packageDependencies": [
- ["toposort", "npm:1.0.7::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftoposort%2Fdownload%2Ftoposort-1.0.7.tgz"]
- ],
- "linkType": "HARD",
- }]
- ]],
["tough-cookie", [
["npm:2.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftough-cookie%2Fdownload%2Ftough-cookie-2.5.0.tgz", {
"packageLocation": "./.yarn/cache/tough-cookie-npm-2.5.0-8c306aca04-bf5d6fac5c.zip/node_modules/tough-cookie/",
@@ -12834,16 +13858,16 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["ts-loader", [
- ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:8.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fts-loader%2Fdownload%2Fts-loader-8.0.1.tgz", {
- "packageLocation": "./.yarn/$$virtual/ts-loader-virtual-c9fdabebac/0/cache/ts-loader-npm-8.0.1-1b9a0b71e4-62772faf48.zip/node_modules/ts-loader/",
+ ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:8.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fts-loader%2Fdownload%2Fts-loader-8.0.3.tgz", {
+ "packageLocation": "./.yarn/$$virtual/ts-loader-virtual-003ba42bda/0/cache/ts-loader-npm-8.0.3-6f80c35b73-fe39e52d6f.zip/node_modules/ts-loader/",
"packageDependencies": [
- ["ts-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:8.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fts-loader%2Fdownload%2Fts-loader-8.0.1.tgz"],
+ ["ts-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:8.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fts-loader%2Fdownload%2Fts-loader-8.0.3.tgz"],
["chalk", "npm:2.4.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-2.4.2.tgz"],
["enhanced-resolve", "npm:4.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fenhanced-resolve%2Fdownload%2Fenhanced-resolve-4.3.0.tgz"],
["loader-utils", "npm:1.4.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-utils%2Fdownload%2Floader-utils-1.4.0.tgz"],
["micromatch", "npm:4.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fmicromatch%2Fdownload%2Fmicromatch-4.0.2.tgz"],
["semver", "npm:6.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-6.3.0.tgz"],
- ["typescript", "patch:typescript@npm%3A3.9.7%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-3.9.7.tgz#builtin<compat/typescript>::version=3.9.7&hash=5b02a2"]
+ ["typescript", "patch:typescript@npm%3A4.0.2%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-4.0.2.tgz#builtin<compat/typescript>::version=4.0.2&hash=5b02a2"]
],
"packagePeers": [
"typescript"
@@ -12874,24 +13898,24 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["tsutils", [
- ["virtual:3188411791b9b17064a0b4716d5f9f317fab9aca03a2adad8703c8c0c871289085f9fb2d89f69d61307afa5661ddcb03fe2b5bfb5820dc0232403037c0dac9cb#npm:3.17.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsutils%2Fdownload%2Ftsutils-3.17.1.tgz", {
- "packageLocation": "./.yarn/$$virtual/tsutils-virtual-225756ca27/0/cache/tsutils-npm-3.17.1-e58260689c-bed8ff7998.zip/node_modules/tsutils/",
+ ["virtual:6b090f53c60ffa0b7aaef0ced1caa498287b02ac23431999e7b6354a77c6335756f1b98cede1091b7477651df82c3e43da90a593747dbb5c19e306c383157b84#npm:3.17.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsutils%2Fdownload%2Ftsutils-3.17.1.tgz", {
+ "packageLocation": "./.yarn/$$virtual/tsutils-virtual-099ba65825/0/cache/tsutils-npm-3.17.1-e58260689c-bed8ff7998.zip/node_modules/tsutils/",
"packageDependencies": [
- ["tsutils", "virtual:3188411791b9b17064a0b4716d5f9f317fab9aca03a2adad8703c8c0c871289085f9fb2d89f69d61307afa5661ddcb03fe2b5bfb5820dc0232403037c0dac9cb#npm:3.17.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsutils%2Fdownload%2Ftsutils-3.17.1.tgz"],
+ ["tsutils", "virtual:6b090f53c60ffa0b7aaef0ced1caa498287b02ac23431999e7b6354a77c6335756f1b98cede1091b7477651df82c3e43da90a593747dbb5c19e306c383157b84#npm:3.17.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsutils%2Fdownload%2Ftsutils-3.17.1.tgz"],
["tslib", "npm:1.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftslib%2Fdownload%2Ftslib-1.13.0.tgz"],
- ["typescript", null]
+ ["typescript", "patch:typescript@npm%3A4.0.2%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-4.0.2.tgz#builtin<compat/typescript>::version=4.0.2&hash=5b02a2"]
],
"packagePeers": [
"typescript"
],
"linkType": "HARD",
}],
- ["virtual:7711a57149a350acf71614f15e4d5dde0ed80fd3f6b9aac11b49aa0f1900f1b05731e0e43a37fe8f0fa730942e0de5e80e4aca1a0df7ded2ab03d0bb11716c42#npm:3.17.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsutils%2Fdownload%2Ftsutils-3.17.1.tgz", {
- "packageLocation": "./.yarn/$$virtual/tsutils-virtual-b15699e85e/0/cache/tsutils-npm-3.17.1-e58260689c-bed8ff7998.zip/node_modules/tsutils/",
+ ["virtual:74f3ce4730be82a39c05577948e092efbe436415fbae850d9d5d07bee35df41e3ecfd8a5b58d019a2990d0c5ad4c8a28fe10a468f8ed2307a1f4ca468609e708#npm:3.17.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsutils%2Fdownload%2Ftsutils-3.17.1.tgz", {
+ "packageLocation": "./.yarn/$$virtual/tsutils-virtual-4142714550/0/cache/tsutils-npm-3.17.1-e58260689c-bed8ff7998.zip/node_modules/tsutils/",
"packageDependencies": [
- ["tsutils", "virtual:7711a57149a350acf71614f15e4d5dde0ed80fd3f6b9aac11b49aa0f1900f1b05731e0e43a37fe8f0fa730942e0de5e80e4aca1a0df7ded2ab03d0bb11716c42#npm:3.17.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsutils%2Fdownload%2Ftsutils-3.17.1.tgz"],
+ ["tsutils", "virtual:74f3ce4730be82a39c05577948e092efbe436415fbae850d9d5d07bee35df41e3ecfd8a5b58d019a2990d0c5ad4c8a28fe10a468f8ed2307a1f4ca468609e708#npm:3.17.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsutils%2Fdownload%2Ftsutils-3.17.1.tgz"],
["tslib", "npm:1.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftslib%2Fdownload%2Ftslib-1.13.0.tgz"],
- ["typescript", "patch:typescript@npm%3A3.9.7%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-3.9.7.tgz#builtin<compat/typescript>::version=3.9.7&hash=5b02a2"]
+ ["typescript", null]
],
"packagePeers": [
"typescript"
@@ -12992,21 +14016,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["typescript", [
- ["patch:typescript@npm%3A3.9.7%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-3.9.7.tgz#builtin<compat/typescript>::version=3.9.7&hash=5b02a2", {
- "packageLocation": "./.yarn/cache/typescript-patch-1168a30d2c-f0d3d9c987.zip/node_modules/typescript/",
+ ["patch:typescript@npm%3A4.0.2%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-4.0.2.tgz#builtin<compat/typescript>::version=4.0.2&hash=5b02a2", {
+ "packageLocation": "./.yarn/cache/typescript-patch-ad8d4a081d-b8b689ef99.zip/node_modules/typescript/",
"packageDependencies": [
- ["typescript", "patch:typescript@npm%3A3.9.7%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-3.9.7.tgz#builtin<compat/typescript>::version=3.9.7&hash=5b02a2"]
- ],
- "linkType": "HARD",
- }]
- ]],
- ["uglify-js", [
- ["npm:3.4.10::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fuglify-js%2Fdownload%2Fuglify-js-3.4.10.tgz", {
- "packageLocation": "./.yarn/cache/uglify-js-npm-3.4.10-fe34fe5cff-432811d100.zip/node_modules/uglify-js/",
- "packageDependencies": [
- ["uglify-js", "npm:3.4.10::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fuglify-js%2Fdownload%2Fuglify-js-3.4.10.tgz"],
- ["commander", "npm:2.19.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.19.0.tgz"],
- ["source-map", "npm:0.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.6.1.tgz"]
+ ["typescript", "patch:typescript@npm%3A4.0.2%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-4.0.2.tgz#builtin<compat/typescript>::version=4.0.2&hash=5b02a2"]
],
"linkType": "HARD",
}]
@@ -13158,15 +14171,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD",
}]
]],
- ["upper-case", [
- ["npm:1.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fupper-case%2Fdownload%2Fupper-case-1.1.3.tgz", {
- "packageLocation": "./.yarn/cache/upper-case-npm-1.1.3-1f8aa6bb09-82bfe8d6e1.zip/node_modules/upper-case/",
- "packageDependencies": [
- ["upper-case", "npm:1.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fupper-case%2Fdownload%2Fupper-case-1.1.3.tgz"]
- ],
- "linkType": "HARD",
- }]
- ]],
["uri-js", [
["npm:4.2.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Furi-js%2Fdownload%2Furi-js-4.2.2.tgz", {
"packageLocation": "./.yarn/cache/uri-js-npm-4.2.2-62eea54551-651a49f55d.zip/node_modules/uri-js/",
@@ -13215,7 +14219,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["loader-utils", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-utils%2Fdownload%2Floader-utils-2.0.0.tgz"],
["mime-types", "npm:2.1.27::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime-types%2Fdownload%2Fmime-types-2.1.27.tgz"],
["schema-utils", "npm:2.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fschema-utils%2Fdownload%2Fschema-utils-2.7.0.tgz"],
- ["webpack", "npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz"]
+ ["webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"]
],
"packagePeers": [
"file-loader",
@@ -13377,10 +14381,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["watchpack", [
- ["npm:1.7.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwatchpack%2Fdownload%2Fwatchpack-1.7.2.tgz", {
- "packageLocation": "./.yarn/cache/watchpack-npm-1.7.2-afdd40a391-a9d630dd29.zip/node_modules/watchpack/",
+ ["npm:1.7.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwatchpack%2Fdownload%2Fwatchpack-1.7.4.tgz", {
+ "packageLocation": "./.yarn/cache/watchpack-npm-1.7.4-541041ff61-61876d6e60.zip/node_modules/watchpack/",
"packageDependencies": [
- ["watchpack", "npm:1.7.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwatchpack%2Fdownload%2Fwatchpack-1.7.2.tgz"],
+ ["watchpack", "npm:1.7.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwatchpack%2Fdownload%2Fwatchpack-1.7.4.tgz"],
["chokidar", "npm:3.4.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fchokidar%2Fdownload%2Fchokidar-3.4.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"],
["neo-async", "npm:2.6.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fneo-async%2Fdownload%2Fneo-async-2.6.2.tgz"],
@@ -13410,10 +14414,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]
]],
["webpack", [
- ["npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz", {
- "packageLocation": "./.yarn/cache/webpack-npm-4.43.0-06b502aafb-9f1e6375ba.zip/node_modules/webpack/",
+ ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz", {
+ "packageLocation": "./.yarn/$$virtual/webpack-virtual-6430e17b2d/0/cache/webpack-npm-4.44.1-db6fc92e58-d4d140010b.zip/node_modules/webpack/",
"packageDependencies": [
- ["webpack", "npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz"],
+ ["webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"],
["@webassemblyjs/ast", "npm:1.9.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fast%2Fdownload%2F%40webassemblyjs%2Fast-1.9.0.tgz"],
["@webassemblyjs/helper-module-context", "npm:1.9.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fhelper-module-context%2Fdownload%2F%40webassemblyjs%2Fhelper-module-context-1.9.0.tgz"],
["@webassemblyjs/wasm-edit", "npm:1.9.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fwasm-edit%2Fdownload%2F%40webassemblyjs%2Fwasm-edit-1.9.0.tgz"],
@@ -13434,10 +14438,16 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["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"],
["schema-utils", "npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fschema-utils%2Fdownload%2Fschema-utils-1.0.0.tgz"],
["tapable", "npm:1.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftapable%2Fdownload%2Ftapable-1.1.3.tgz"],
- ["terser-webpack-plugin", "virtual:06b502aafb84fcb61ef20bc57866555a7ce12e440462e300076735b608de2314dcb1fba9be6fa905fe744f9fb2b01b724fa5950152e80298429550725f755eab#npm:1.4.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser-webpack-plugin%2Fdownload%2Fterser-webpack-plugin-1.4.4.tgz"],
- ["watchpack", "npm:1.7.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwatchpack%2Fdownload%2Fwatchpack-1.7.2.tgz"],
+ ["terser-webpack-plugin", "virtual:6430e17b2d0921d17a377f23f4a38fbda5d3da214d48b3ff0c374170f2ef2aaa9c21cce668fadeda53f3fbee00682b7aa1e684eb5ddddd5f4cd69290644b4773#npm:1.4.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser-webpack-plugin%2Fdownload%2Fterser-webpack-plugin-1.4.4.tgz"],
+ ["watchpack", "npm:1.7.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwatchpack%2Fdownload%2Fwatchpack-1.7.4.tgz"],
+ ["webpack-cli", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.3.12::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-cli%2Fdownload%2Fwebpack-cli-3.3.12.tgz"],
+ ["webpack-command", null],
["webpack-sources", "npm:1.4.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-sources%2Fdownload%2Fwebpack-sources-1.4.3.tgz"]
],
+ "packagePeers": [
+ "webpack-cli",
+ "webpack-command"
+ ],
"linkType": "HARD",
}]
]],
@@ -13467,7 +14477,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["loader-utils", "npm:1.4.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-utils%2Fdownload%2Floader-utils-1.4.0.tgz"],
["supports-color", "npm:6.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-6.1.0.tgz"],
["v8-compile-cache", "npm:2.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fv8-compile-cache%2Fdownload%2Fv8-compile-cache-2.1.1.tgz"],
- ["webpack", "npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz"],
+ ["webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"],
["yargs", "npm:13.3.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fyargs%2Fdownload%2Fyargs-13.3.2.tgz"]
],
"packagePeers": [
@@ -13485,7 +14495,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["mime", "npm:2.4.6::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime%2Fdownload%2Fmime-2.4.6.tgz"],
["mkdirp", "npm:0.5.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fmkdirp%2Fdownload%2Fmkdirp-0.5.5.tgz"],
["range-parser", "npm:1.2.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Frange-parser%2Fdownload%2Frange-parser-1.2.1.tgz"],
- ["webpack", "npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz"],
+ ["webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"],
["webpack-log", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-log%2Fdownload%2Fwebpack-log-2.0.0.tgz"]
],
"packagePeers": [
@@ -13528,7 +14538,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["strip-ansi", "npm:3.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-3.0.1.tgz"],
["supports-color", "npm:6.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-6.1.0.tgz"],
["url", "npm:0.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Furl%2Fdownload%2Furl-0.11.0.tgz"],
- ["webpack", "npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz"],
+ ["webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"],
["webpack-cli", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.3.12::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-cli%2Fdownload%2Fwebpack-cli-3.3.12.tgz"],
["webpack-dev-middleware", "virtual:dd7bf9071c15c1b7a313ecdd010711f705a91e516eac87ed27bf82d6945d9d7d9c5b82dec9391533d88e32ec8de8326d7c2bcbfc63ae4f43b290a451f472b891#npm:3.7.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-dev-middleware%2Fdownload%2Fwebpack-dev-middleware-3.7.2.tgz"],
["webpack-log", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-log%2Fdownload%2Fwebpack-log-2.0.0.tgz"],
@@ -13655,7 +14665,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageDependencies": [
["workbox-build", "npm:5.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fworkbox-build%2Fdownload%2Fworkbox-build-5.1.3.tgz"],
["@babel/core", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"],
- ["@babel/preset-env", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-env%2Fdownload%2F%40babel%2Fpreset-env-7.10.4.tgz"],
+ ["@babel/preset-env", "virtual:3e7d201acb70f99b496fd22382494a547adba7ced83157fcf203a35a809a1a86e9fcdadc98baf8c5919858aa7474058982ca7332a042017e29b0e7f90348de11#npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-env%2Fdownload%2F%40babel%2Fpreset-env-7.10.4.tgz"],
["@babel/runtime", "npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fruntime%2Fdownload%2F%40babel%2Fruntime-7.10.5.tgz"],
["@hapi/joi", "npm:15.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40hapi%2Fjoi%2Fdownload%2F%40hapi%2Fjoi-15.1.1.tgz"],
["@rollup/plugin-node-resolve", "virtual:3e7d201acb70f99b496fd22382494a547adba7ced83157fcf203a35a809a1a86e9fcdadc98baf8c5919858aa7474058982ca7332a042017e29b0e7f90348de11#npm:7.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40rollup%2Fplugin-node-resolve%2Fdownload%2F%40rollup%2Fplugin-node-resolve-7.1.3.tgz"],
@@ -13816,7 +14826,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["fast-json-stable-stringify", "npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-json-stable-stringify%2Fdownload%2Ffast-json-stable-stringify-2.1.0.tgz"],
["source-map-url", "npm:0.4.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map-url%2Fdownload%2Fsource-map-url-0.4.0.tgz"],
["upath", "npm:1.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fupath%2Fdownload%2Fupath-1.2.0.tgz"],
- ["webpack", "npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz"],
+ ["webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"],
["webpack-sources", "npm:1.4.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-sources%2Fdownload%2Fwebpack-sources-1.4.3.tgz"],
["workbox-build", "npm:5.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fworkbox-build%2Fdownload%2Fworkbox-build-5.1.3.tgz"]
],
diff --git a/Timeline/ClientApp/.prettierrc b/Timeline/ClientApp/.prettierrc deleted file mode 100644 index 5e59eca6..00000000 --- a/Timeline/ClientApp/.prettierrc +++ /dev/null @@ -1,3 +0,0 @@ -{
- "singleQuote": true
-}
diff --git a/Timeline/ClientApp/package.json b/Timeline/ClientApp/package.json index 921488cd..a2f6e051 100644 --- a/Timeline/ClientApp/package.json +++ b/Timeline/ClientApp/package.json @@ -6,28 +6,28 @@ "keywords": [], "description": "Timeline app.", "dependencies": { - "axios": "^0.19.2", - "bootstrap": "^4.5.0", - "bootstrap-icons": "^1.0.0-alpha4", + "axios": "^0.20.0", + "bootstrap": "^4.5.2", + "bootstrap-icons": "^1.0.0-alpha5", "classnames": "^2.2.6", "clsx": "^1.1.1", "core-js": "^3.6.5", - "i18next": "^19.6.2", - "i18next-browser-languagedetector": "^5.0.0", - "localforage": "^1.7.4", - "lodash": "^4.17.15", + "i18next": "^19.7.0", + "i18next-browser-languagedetector": "^6.0.1", + "localforage": "^1.9.0", + "lodash": "^4.17.20", "pepjs": "^0.5.2", "react": "^16.13.1", "react-dom": "^16.13.1", "react-hot-loader": "^4.12.21", - "react-i18next": "^11.5.0", + "react-i18next": "^11.7.1", "react-inlinesvg": "^2.0.0", "react-responsive": "^8.1.0", "react-router": "^5.2.0", "react-router-dom": "^5.2.0", - "reactstrap": "^8.4.1", - "regenerator-runtime": "^0.13.5", - "rxjs": "^6.5.5", + "reactstrap": "^8.5.1", + "regenerator-runtime": "^0.13.7", + "rxjs": "^6.6.2", "workbox-precaching": "^5.1.3", "workbox-routing": "^5.1.3", "workbox-strategies": "^5.1.3", @@ -53,59 +53,59 @@ ] }, "devDependencies": { - "@babel/core": "^7.10.5", - "@babel/plugin-proposal-class-properties": "^7.10.1", + "@babel/core": "^7.11.4", + "@babel/plugin-proposal-class-properties": "^7.10.4", "@babel/plugin-proposal-decorators": "^7.10.5", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.1", - "@babel/plugin-proposal-optional-chaining": "^7.10.1", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4", + "@babel/plugin-proposal-optional-chaining": "^7.11.0", "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/preset-env": "^7.10.2", - "@babel/preset-react": "^7.10.1", - "@babel/preset-typescript": "^7.10.1", + "@babel/preset-env": "^7.11.0", + "@babel/preset-react": "^7.10.4", + "@babel/preset-typescript": "^7.10.4", "@hot-loader/react-dom": "^16.13.0", "@types/classnames": "^2.2.10", "@types/crypto-js": "^3.1.47", - "@types/lodash": "^4.14.155", - "@types/node": "^14.0.11", - "@types/react": "^16.9.35", + "@types/lodash": "^4.14.159", + "@types/node": "^14.6.0", + "@types/react": "^16.9.46", "@types/react-dom": "^16.9.8", "@types/react-responsive": "^8.0.2", - "@types/react-router": "^5.1.7", + "@types/react-router": "^5.1.8", "@types/react-router-dom": "^5.1.5", - "@types/reactstrap": "^8.4.2", + "@types/reactstrap": "^8.5.1", "@types/webpack-env": "^1.15.2", "@types/xregexp": "^4.3.0", - "@typescript-eslint/eslint-plugin": "^3.6.1", - "@typescript-eslint/parser": "^3.6.1", + "@typescript-eslint/eslint-plugin": "^3.9.1", + "@typescript-eslint/parser": "^3.9.1", "@yarnpkg/pnpify": "^2.1.0", "babel-loader": "^8.1.0", "babel-plugin-transform-builtin-extend": "^1.1.2", "clean-webpack-plugin": "^3.0.0", - "copy-webpack-plugin": "^6.0.2", + "copy-webpack-plugin": "^6.0.3", "crypto-js": "^4.0.0", - "css-loader": "^3.5.3", - "eslint": "^7.2.0", + "css-loader": "^4.2.1", + "eslint": "^7.7.0", "eslint-config-prettier": "^6.11.0", - "eslint-plugin-prettier": "^3.1.3", - "eslint-plugin-react": "^7.20.0", - "eslint-plugin-react-hooks": "^4.0.8", + "eslint-plugin-prettier": "^3.1.4", + "eslint-plugin-react": "^7.20.6", + "eslint-plugin-react-hooks": "^4.1.0", "file-loader": "^6.0.0", - "html-webpack-plugin": "^3.2.0", + "html-webpack-plugin": "^4.3.0", "http-server": "^0.12.3", "mini-css-extract-plugin": "^0.10.0", "pnp-webpack-plugin": "^1.6.4", "postcss-loader": "^3.0.0", "postcss-preset-env": "^6.7.0", - "prettier": "^2.0.5", - "sass": "^1.26.8", - "sass-loader": "^9.0.2", + "prettier": "^2.1.0", + "sass": "^1.26.10", + "sass-loader": "^9.0.3", "style-loader": "^1.2.1", - "ts-loader": "^8.0.1", - "typescript": "^3.9.7", + "ts-loader": "^8.0.3", + "typescript": "^4.0.2", "url-loader": "^4.1.0", - "webpack": "^4.43.0", + "webpack": "^4.44.1", "webpack-chain": "^6.5.1", - "webpack-cli": "^3.3.11", + "webpack-cli": "^3.3.12", "webpack-dev-server": "^3.11.0", "workbox-webpack-plugin": "^5.1.3" } diff --git a/Timeline/ClientApp/src/app/App.tsx b/Timeline/ClientApp/src/app/App.tsx index 31ff9a4e..7b382c2f 100644 --- a/Timeline/ClientApp/src/app/App.tsx +++ b/Timeline/ClientApp/src/app/App.tsx @@ -1,88 +1,88 @@ -import React from 'react';
-import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
-import { hot } from 'react-hot-loader/root';
-
-import AppBar from './common/AppBar';
-import LoadingPage from './common/LoadingPage';
-import Home from './home/Home';
-import Login from './user/Login';
-import Settings from './settings/Settings';
-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';
-
-const NoMatch: React.FC = () => {
- return (
- <>
- <AppBar />
- <div style={{ height: 56 }} />
- <div>Ah-oh, 404!</div>
- </>
- );
-};
-
-const LazyAdmin = React.lazy(() =>
- import(/* webpackChunkName: "admin" */ './admin/Admin')
-);
-
-const App: React.FC = () => {
- const [loading, setLoading] = React.useState<boolean>(true);
-
- const user = useRawUser();
-
- React.useEffect(() => {
- void userService.checkLoginState();
- void dataStorage.ready().then(() => setLoading(false));
- }, []);
-
- let body;
- if (user === undefined || loading) {
- body = <LoadingPage />;
- } else {
- body = (
- <Router>
- <Switch>
- <Route exact path="/">
- <Home />
- </Route>
- <Route exact path="/login">
- <Login />
- </Route>
- <Route path="/settings">
- <Settings />
- </Route>
- <Route path="/about">
- <About />
- </Route>
- <Route path="/timelines/:name">
- <TimelinePage />
- </Route>
- <Route path="/users/:username">
- <User />
- </Route>
- {user && user.administrator && (
- <Route path="/admin">
- <LazyAdmin user={user} />
- </Route>
- )}
- <Route>
- <NoMatch />
- </Route>
- </Switch>
- </Router>
- );
- }
-
- return (
- <React.Suspense fallback={<LoadingPage />}>
- {body}
- <AlertHost />
- </React.Suspense>
- );
-};
-
-export default hot(App);
+import React from "react"; +import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; +import { hot } from "react-hot-loader/root"; + +import AppBar from "./common/AppBar"; +import LoadingPage from "./common/LoadingPage"; +import Home from "./home/Home"; +import Login from "./user/Login"; +import Settings from "./settings/Settings"; +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"; + +const NoMatch: React.FC = () => { + return ( + <> + <AppBar /> + <div style={{ height: 56 }} /> + <div>Ah-oh, 404!</div> + </> + ); +}; + +const LazyAdmin = React.lazy( + () => import(/* webpackChunkName: "admin" */ "./admin/Admin") +); + +const App: React.FC = () => { + const [loading, setLoading] = React.useState<boolean>(true); + + const user = useRawUser(); + + React.useEffect(() => { + void userService.checkLoginState(); + void dataStorage.ready().then(() => setLoading(false)); + }, []); + + let body; + if (user === undefined || loading) { + body = <LoadingPage />; + } else { + body = ( + <Router> + <Switch> + <Route exact path="/"> + <Home /> + </Route> + <Route exact path="/login"> + <Login /> + </Route> + <Route path="/settings"> + <Settings /> + </Route> + <Route path="/about"> + <About /> + </Route> + <Route path="/timelines/:name"> + <TimelinePage /> + </Route> + <Route path="/users/:username"> + <User /> + </Route> + {user && user.administrator && ( + <Route path="/admin"> + <LazyAdmin user={user} /> + </Route> + )} + <Route> + <NoMatch /> + </Route> + </Switch> + </Router> + ); + } + + return ( + <React.Suspense fallback={<LoadingPage />}> + {body} + <AlertHost /> + </React.Suspense> + ); +}; + +export default hot(App); diff --git a/Timeline/ClientApp/src/app/about/About.tsx b/Timeline/ClientApp/src/app/about/About.tsx index 38e16c7c..751fca14 100644 --- a/Timeline/ClientApp/src/app/about/About.tsx +++ b/Timeline/ClientApp/src/app/about/About.tsx @@ -1,172 +1,172 @@ -import React from 'react';
-import { useTranslation, Trans } from 'react-i18next';
-
-import authorAvatarUrl from './author-avatar.png';
-import githubLogoUrl from './github.png';
-
-import AppBar from '../common/AppBar';
-
-const frontendCredits: {
- name: string;
- url: string;
-}[] = [
- {
- name: 'reactjs',
- url: 'https://reactjs.org',
- },
- {
- name: 'typescript',
- url: 'https://www.typescriptlang.org',
- },
- {
- name: 'bootstrap',
- url: 'https://getbootstrap.com',
- },
- {
- name: 'reactstrap',
- url: 'https://reactstrap.github.io',
- },
- {
- name: 'babeljs',
- url: 'https://babeljs.io',
- },
- {
- name: 'webpack',
- url: 'https://webpack.js.org',
- },
- {
- name: 'sass',
- url: 'https://sass-lang.com',
- },
- {
- name: 'eslint',
- url: 'https://eslint.org',
- },
- {
- name: 'prettier',
- url: 'https://prettier.io',
- },
- {
- name: 'pepjs',
- url: 'https://github.com/jquery/PEP',
- },
- {
- name: 'react-inlinesvg',
- url: 'https://github.com/gilbarbara/react-inlinesvg',
- },
-];
-
-const backendCredits: {
- name: string;
- url: string;
-}[] = [
- {
- name: 'ASP.NET Core',
- url: 'https://dotnet.microsoft.com/learn/aspnet/what-is-aspnet-core',
- },
- { name: 'sqlite', url: 'https://sqlite.org' },
- {
- name: 'ImageSharp',
- url: 'https://github.com/SixLabors/ImageSharp',
- },
-];
-
-const About: React.FC = () => {
- const { t } = useTranslation();
-
- return (
- <>
- <AppBar />
- <div className="mt-appbar px-2 mb-4">
- <div className="container mt-4 py-3 shadow border border-primary rounded bg-light">
- <h4 id="author-info">{t('about.author.title')}</h4>
- <div>
- <div className="d-flex">
- <img
- src={authorAvatarUrl}
- className="align-self-start avatar large rounded-circle"
- />
- <div>
- <p>
- <small>{t('about.author.fullname')}</small>
- <span className="text-primary">杨宇千</span>
- </p>
- <p>
- <small>{t('about.author.nickname')}</small>
- <span className="text-primary">crupest</span>
- </p>
- <p>
- <small>{t('about.author.introduction')}</small>
- {t('about.author.introductionContent')}
- </p>
- </div>
- </div>
- <p>
- <small>{t('about.author.links')}</small>
- <a
- href="https://github.com/crupest"
- target="_blank"
- rel="noopener noreferrer"
- >
- <img
- src={githubLogoUrl}
- className="about-link-icon text-body"
- />
- </a>
- </p>
- </div>
- </div>
- <div className="container mt-4 py-3 shadow border border-primary rounded bg-light">
- <h4>{t('about.site.title')}</h4>
- <p>
- <Trans i18nKey="about.site.content">
- 0<span className="text-primary">1</span>2<b>3</b>4
- <a href="#author-info">5</a>6
- </Trans>
- </p>
- <p>
- <a
- href="https://github.com/crupest/Timeline"
- target="_blank"
- rel="noopener noreferrer"
- >
- {t('about.site.repo')}
- </a>
- </p>
- </div>
- <div className="container mt-4 py-3 shadow border border-primary rounded bg-light">
- <h4>{t('about.credits.title')}</h4>
- <p>{t('about.credits.content')}</p>
- <p>{t('about.credits.frontend')}</p>
- <ul>
- {frontendCredits.map((item, index) => {
- return (
- <li key={index}>
- <a href={item.url} target="_blank" rel="noopener noreferrer">
- {item.name}
- </a>
- </li>
- );
- })}
- <li>...</li>
- </ul>
- <p>{t('about.credits.backend')}</p>
- <ul>
- {backendCredits.map((item, index) => {
- return (
- <li key={index}>
- <a href={item.url} target="_blank" rel="noopener noreferrer">
- {item.name}
- </a>
- </li>
- );
- })}
- <li>...</li>
- </ul>
- </div>
- </div>
- </>
- );
-};
-
-export default About;
+import React from "react"; +import { useTranslation, Trans } from "react-i18next"; + +import authorAvatarUrl from "./author-avatar.png"; +import githubLogoUrl from "./github.png"; + +import AppBar from "../common/AppBar"; + +const frontendCredits: { + name: string; + url: string; +}[] = [ + { + name: "reactjs", + url: "https://reactjs.org", + }, + { + name: "typescript", + url: "https://www.typescriptlang.org", + }, + { + name: "bootstrap", + url: "https://getbootstrap.com", + }, + { + name: "reactstrap", + url: "https://reactstrap.github.io", + }, + { + name: "babeljs", + url: "https://babeljs.io", + }, + { + name: "webpack", + url: "https://webpack.js.org", + }, + { + name: "sass", + url: "https://sass-lang.com", + }, + { + name: "eslint", + url: "https://eslint.org", + }, + { + name: "prettier", + url: "https://prettier.io", + }, + { + name: "pepjs", + url: "https://github.com/jquery/PEP", + }, + { + name: "react-inlinesvg", + url: "https://github.com/gilbarbara/react-inlinesvg", + }, +]; + +const backendCredits: { + name: string; + url: string; +}[] = [ + { + name: "ASP.NET Core", + url: "https://dotnet.microsoft.com/learn/aspnet/what-is-aspnet-core", + }, + { name: "sqlite", url: "https://sqlite.org" }, + { + name: "ImageSharp", + url: "https://github.com/SixLabors/ImageSharp", + }, +]; + +const About: React.FC = () => { + const { t } = useTranslation(); + + return ( + <> + <AppBar /> + <div className="mt-appbar px-2 mb-4"> + <div className="container mt-4 py-3 shadow border border-primary rounded bg-light"> + <h4 id="author-info">{t("about.author.title")}</h4> + <div> + <div className="d-flex"> + <img + src={authorAvatarUrl} + className="align-self-start avatar large rounded-circle" + /> + <div> + <p> + <small>{t("about.author.fullname")}</small> + <span className="text-primary">杨宇千</span> + </p> + <p> + <small>{t("about.author.nickname")}</small> + <span className="text-primary">crupest</span> + </p> + <p> + <small>{t("about.author.introduction")}</small> + {t("about.author.introductionContent")} + </p> + </div> + </div> + <p> + <small>{t("about.author.links")}</small> + <a + href="https://github.com/crupest" + target="_blank" + rel="noopener noreferrer" + > + <img + src={githubLogoUrl} + className="about-link-icon text-body" + /> + </a> + </p> + </div> + </div> + <div className="container mt-4 py-3 shadow border border-primary rounded bg-light"> + <h4>{t("about.site.title")}</h4> + <p> + <Trans i18nKey="about.site.content"> + 0<span className="text-primary">1</span>2<b>3</b>4 + <a href="#author-info">5</a>6 + </Trans> + </p> + <p> + <a + href="https://github.com/crupest/Timeline" + target="_blank" + rel="noopener noreferrer" + > + {t("about.site.repo")} + </a> + </p> + </div> + <div className="container mt-4 py-3 shadow border border-primary rounded bg-light"> + <h4>{t("about.credits.title")}</h4> + <p>{t("about.credits.content")}</p> + <p>{t("about.credits.frontend")}</p> + <ul> + {frontendCredits.map((item, index) => { + return ( + <li key={index}> + <a href={item.url} target="_blank" rel="noopener noreferrer"> + {item.name} + </a> + </li> + ); + })} + <li>...</li> + </ul> + <p>{t("about.credits.backend")}</p> + <ul> + {backendCredits.map((item, index) => { + return ( + <li key={index}> + <a href={item.url} target="_blank" rel="noopener noreferrer"> + {item.name} + </a> + </li> + ); + })} + <li>...</li> + </ul> + </div> + </div> + </> + ); +}; + +export default About; diff --git a/Timeline/ClientApp/src/app/about/about.sass b/Timeline/ClientApp/src/app/about/about.sass index f4d00cae..3b5840cd 100644 --- a/Timeline/ClientApp/src/app/about/about.sass +++ b/Timeline/ClientApp/src/app/about/about.sass @@ -1,4 +1,4 @@ -.about-link-icon
- @extend .mx-2
- width: 1.2em
- height: 1.2em
+.about-link-icon + @extend .mx-2 + width: 1.2em + height: 1.2em diff --git a/Timeline/ClientApp/src/app/admin/Admin.tsx b/Timeline/ClientApp/src/app/admin/Admin.tsx index af07dd2b..2f8b2c05 100644 --- a/Timeline/ClientApp/src/app/admin/Admin.tsx +++ b/Timeline/ClientApp/src/app/admin/Admin.tsx @@ -1,78 +1,78 @@ -import React, { Fragment } from 'react';
-import { Nav, NavItem, NavLink } from 'reactstrap';
-import {
- Redirect,
- Route,
- Switch,
- useRouteMatch,
- useHistory
-} from 'react-router';
-import classnames from 'classnames';
-
-import AppBar from '../common/AppBar';
-import UserAdmin from './UserAdmin';
-
-import { UserWithToken } from '../data/user';
-
-interface AdminProps {
- user: UserWithToken;
-}
-
-const Admin: React.FC<AdminProps> = props => {
- const match = useRouteMatch();
- const history = useHistory();
- type TabNames = 'users' | 'more';
-
- const tabName = history.location.pathname.replace(match.path + '/', '');
-
- function toggle(newTab: TabNames): void {
- history.push(`${match.url}/${newTab}`);
- }
-
- const createRoute = (
- name: string,
- body: React.ReactNode
- ): React.ReactNode => {
- return (
- <Route path={`${match.path}/${name}`}>
- <AppBar />
- <div style={{ height: 56 }} className="flex-fix-length" />
- <Nav tabs>
- <NavItem>
- <NavLink
- className={classnames({ active: tabName === 'users' })}
- onClick={() => {
- toggle('users');
- }}
- >
- Users
- </NavLink>
- </NavItem>
- <NavItem>
- <NavLink
- className={classnames({ active: tabName === 'more' })}
- onClick={() => {
- toggle('more');
- }}
- >
- More
- </NavLink>
- </NavItem>
- </Nav>
- {body}
- </Route>
- );
- };
-
- return (
- <Fragment>
- <Switch>
- <Redirect from={match.path} to={`${match.path}/users`} exact />
- {createRoute('users', <UserAdmin user={props.user} />)}
- {createRoute('more', <div>More Page Works</div>)}
- </Switch>
- </Fragment>
- );
-};
-
-export default Admin;
+import React, { Fragment } from "react"; +import { Nav, NavItem, NavLink } from "reactstrap"; +import { + Redirect, + Route, + Switch, + useRouteMatch, + useHistory, +} from "react-router"; +import classnames from "classnames"; + +import AppBar from "../common/AppBar"; +import UserAdmin from "./UserAdmin"; + +import { UserWithToken } from "../data/user"; + +interface AdminProps { + user: UserWithToken; +} + +const Admin: React.FC<AdminProps> = (props) => { + const match = useRouteMatch(); + const history = useHistory(); + type TabNames = "users" | "more"; + + const tabName = history.location.pathname.replace(match.path + "/", ""); + + function toggle(newTab: TabNames): void { + history.push(`${match.url}/${newTab}`); + } + + const createRoute = ( + name: string, + body: React.ReactNode + ): React.ReactNode => { + return ( + <Route path={`${match.path}/${name}`}> + <AppBar /> + <div style={{ height: 56 }} className="flex-fix-length" /> + <Nav tabs> + <NavItem> + <NavLink + className={classnames({ active: tabName === "users" })} + onClick={() => { + toggle("users"); + }} + > + Users + </NavLink> + </NavItem> + <NavItem> + <NavLink + className={classnames({ active: tabName === "more" })} + onClick={() => { + toggle("more"); + }} + > + More + </NavLink> + </NavItem> + </Nav> + {body} + </Route> + ); + }; + + return ( + <Fragment> + <Switch> + <Redirect from={match.path} to={`${match.path}/users`} exact /> + {createRoute("users", <UserAdmin user={props.user} />)} + {createRoute("more", <div>More Page Works</div>)} + </Switch> + </Fragment> + ); +}; + +export default Admin; diff --git a/Timeline/ClientApp/src/app/admin/UserAdmin.tsx b/Timeline/ClientApp/src/app/admin/UserAdmin.tsx index a3115073..57eed455 100644 --- a/Timeline/ClientApp/src/app/admin/UserAdmin.tsx +++ b/Timeline/ClientApp/src/app/admin/UserAdmin.tsx @@ -1,464 +1,464 @@ -import React, { useState, useEffect } from 'react';
-import {
- ListGroupItem,
- Row,
- Col,
- UncontrolledDropdown,
- DropdownToggle,
- DropdownMenu,
- DropdownItem,
- Spinner,
- Button,
-} from 'reactstrap';
-import axios from 'axios';
-
-import OperationDialog from '../common/OperationDialog';
-
-import { User, UserWithToken } from '../data/user';
-
-const apiBaseUrl = '/api';
-
-async function fetchUserList(_token: string): Promise<User[]> {
- const res = await axios.get<User[]>(`${apiBaseUrl}/users`);
- return res.data;
-}
-
-interface CreateUserInfo {
- username: string;
- password: string;
- administrator: boolean;
-}
-
-async function createUser(user: CreateUserInfo, token: string): Promise<User> {
- const res = await axios.post<User>(
- `${apiBaseUrl}/userop/createuser?token=${token}`,
- user
- );
- return res.data;
-}
-
-function deleteUser(username: string, token: string): Promise<void> {
- return axios.delete(`${apiBaseUrl}/users/${username}?token=${token}`);
-}
-
-function changeUsername(
- oldUsername: string,
- newUsername: string,
- token: string
-): Promise<void> {
- return axios.patch(`${apiBaseUrl}/users/${oldUsername}?token=${token}`, {
- username: newUsername,
- });
-}
-
-function changePassword(
- username: string,
- newPassword: string,
- token: string
-): Promise<void> {
- return axios.patch(`${apiBaseUrl}/users/${username}?token=${token}`, {
- password: newPassword,
- });
-}
-
-function changePermission(
- username: string,
- newPermission: boolean,
- token: string
-): Promise<void> {
- return axios.patch(`${apiBaseUrl}/users/${username}?token=${token}`, {
- administrator: newPermission,
- });
-}
-
-const kChangeUsername = 'changeusername';
-const kChangePassword = 'changepassword';
-const kChangePermission = 'changepermission';
-const kDelete = 'delete';
-
-type TChangeUsername = typeof kChangeUsername;
-type TChangePassword = typeof kChangePassword;
-type TChangePermission = typeof kChangePermission;
-type TDelete = typeof kDelete;
-
-type ContextMenuItem =
- | TChangeUsername
- | TChangePassword
- | TChangePermission
- | TDelete;
-
-interface UserCardProps {
- onContextMenu: (item: ContextMenuItem) => void;
- user: User;
-}
-
-const UserItem: React.FC<UserCardProps> = (props) => {
- const user = props.user;
-
- const createClickCallback = (item: ContextMenuItem): (() => void) => {
- return () => {
- props.onContextMenu(item);
- };
- };
-
- return (
- <ListGroupItem className="container">
- <Row className="align-items-center">
- <Col>
- <p className="mb-0 text-primary">{user.username}</p>
- <small
- className={user.administrator ? 'text-danger' : 'text-secondary'}
- >
- {user.administrator ? 'administrator' : 'user'}
- </small>
- </Col>
- <Col className="col-auto">
- <UncontrolledDropdown>
- <DropdownToggle color="warning" className="text-light" caret>
- Manage
- </DropdownToggle>
- <DropdownMenu>
- <DropdownItem onClick={createClickCallback(kChangeUsername)}>
- Change Username
- </DropdownItem>
- <DropdownItem onClick={createClickCallback(kChangePassword)}>
- Change Password
- </DropdownItem>
- <DropdownItem onClick={createClickCallback(kChangePermission)}>
- Change Permission
- </DropdownItem>
- <DropdownItem
- className="text-danger"
- onClick={createClickCallback(kDelete)}
- >
- Delete
- </DropdownItem>
- </DropdownMenu>
- </UncontrolledDropdown>
- </Col>
- </Row>
- </ListGroupItem>
- );
-};
-
-interface DialogProps {
- open: boolean;
- close: () => void;
-}
-
-interface CreateUserDialogProps extends DialogProps {
- process: (user: CreateUserInfo) => Promise<void>;
-}
-
-const CreateUserDialog: React.FC<CreateUserDialogProps> = (props) => {
- return (
- <OperationDialog
- title="Create"
- titleColor="create"
- inputPrompt="You are creating a new user."
- inputScheme={[
- { type: 'text', label: 'Username' },
- { type: 'text', label: 'Password' },
- { type: 'bool', label: 'Administrator' },
- ]}
- onProcess={([username, password, administrator]) =>
- props.process({
- username: username as string,
- password: password as string,
- administrator: administrator as boolean,
- })
- }
- close={props.close}
- open={props.open}
- />
- );
-};
-
-const UsernameLabel: React.FC = (props) => {
- return <span style={{ color: 'blue' }}>{props.children}</span>;
-};
-
-interface UserDeleteDialogProps extends DialogProps {
- username: string;
- process: () => Promise<void>;
-}
-
-const UserDeleteDialog: React.FC<UserDeleteDialogProps> = (props) => {
- return (
- <OperationDialog
- open={props.open}
- close={props.close}
- title="Dangerous"
- titleColor="dangerous"
- inputPrompt={() => (
- <>
- {'You are deleting user '}
- <UsernameLabel>{props.username}</UsernameLabel>
- {' !'}
- </>
- )}
- onProcess={props.process}
- />
- );
-};
-
-interface UserModifyDialogProps<T> extends DialogProps {
- username: string;
- process: (value: T) => Promise<void>;
-}
-
-const UserChangeUsernameDialog: React.FC<UserModifyDialogProps<string>> = (
- props
-) => {
- return (
- <OperationDialog
- open={props.open}
- close={props.close}
- title="Caution"
- titleColor="dangerous"
- inputPrompt={() => (
- <>
- {'You are change the username of user '}
- <UsernameLabel>{props.username}</UsernameLabel>
- {' !'}
- </>
- )}
- inputScheme={[{ type: 'text', label: 'New Username' }]}
- onProcess={([newUsername]) => {
- return props.process(newUsername as string);
- }}
- />
- );
-};
-
-const UserChangePasswordDialog: React.FC<UserModifyDialogProps<string>> = (
- props
-) => {
- return (
- <OperationDialog
- open={props.open}
- close={props.close}
- title="Caution"
- titleColor="dangerous"
- inputPrompt={() => (
- <>
- {'You are change the password of user '}
- <UsernameLabel>{props.username}</UsernameLabel>
- {' !'}
- </>
- )}
- inputScheme={[{ type: 'text', label: 'New Password' }]}
- onProcess={([newPassword]) => {
- return props.process(newPassword as string);
- }}
- />
- );
-};
-
-interface UserChangePermissionDialogProps extends DialogProps {
- username: string;
- newPermission: boolean;
- process: () => Promise<void>;
-}
-
-const UserChangePermissionDialog: React.FC<UserChangePermissionDialogProps> = (
- props
-) => {
- return (
- <OperationDialog
- open={props.open}
- close={props.close}
- title="Caution"
- titleColor="dangerous"
- inputPrompt={() => (
- <>
- {'You are change user '}
- <UsernameLabel>{props.username}</UsernameLabel>
- {' to '}
- <span style={{ color: 'orange' }}>
- {props.newPermission ? 'administrator' : 'normal user'}
- </span>
- {' !'}
- </>
- )}
- onProcess={props.process}
- />
- );
-};
-
-interface UserAdminProps {
- user: UserWithToken;
-}
-
-const UserAdmin: React.FC<UserAdminProps> = (props) => {
- type DialogInfo =
- | null
- | {
- type: 'create';
- }
- | { type: TDelete; username: string }
- | {
- type: TChangeUsername;
- username: string;
- }
- | {
- type: TChangePassword;
- username: string;
- }
- | {
- type: TChangePermission;
- username: string;
- newPermission: boolean;
- };
-
- const [users, setUsers] = useState<User[] | null>(null);
- const [dialog, setDialog] = useState<DialogInfo>(null);
-
- const token = props.user.token;
-
- useEffect(() => {
- let subscribe = true;
- void fetchUserList(props.user.token).then((us) => {
- if (subscribe) {
- setUsers(us);
- }
- });
- return () => {
- subscribe = false;
- };
- }, [props.user]);
-
- let dialogNode: React.ReactNode;
- if (dialog)
- switch (dialog.type) {
- case 'create':
- dialogNode = (
- <CreateUserDialog
- open
- close={() => setDialog(null)}
- process={async (user) => {
- const u = await createUser(user, token);
- setUsers((oldUsers) => [...(oldUsers ?? []), u]);
- }}
- />
- );
- break;
- case 'delete':
- dialogNode = (
- <UserDeleteDialog
- open
- close={() => setDialog(null)}
- username={dialog.username}
- process={async () => {
- await deleteUser(dialog.username, token);
- setUsers((oldUsers) =>
- (oldUsers ?? []).filter((u) => u.username !== dialog.username)
- );
- }}
- />
- );
- break;
- case kChangeUsername:
- dialogNode = (
- <UserChangeUsernameDialog
- open
- close={() => setDialog(null)}
- username={dialog.username}
- process={async (newUsername) => {
- await changeUsername(dialog.username, newUsername, token);
- setUsers((oldUsers) => {
- const users = (oldUsers ?? []).slice();
- const findedUser = users.find(
- (u) => u.username === dialog.username
- );
- if (findedUser) findedUser.username = newUsername;
- return users;
- });
- }}
- />
- );
- break;
- case kChangePassword:
- dialogNode = (
- <UserChangePasswordDialog
- open
- close={() => setDialog(null)}
- username={dialog.username}
- process={async (newPassword) => {
- await changePassword(dialog.username, newPassword, token);
- }}
- />
- );
- break;
- case kChangePermission: {
- const newPermission = dialog.newPermission;
- dialogNode = (
- <UserChangePermissionDialog
- open
- close={() => setDialog(null)}
- username={dialog.username}
- newPermission={newPermission}
- process={async () => {
- await changePermission(dialog.username, newPermission, token);
- setUsers((oldUsers) => {
- const users = (oldUsers ?? []).slice();
- const findedUser = users.find(
- (u) => u.username === dialog.username
- );
- if (findedUser) findedUser.administrator = newPermission;
- return users;
- });
- }}
- />
- );
- break;
- }
- }
-
- if (users) {
- const userComponents = users.map((user) => {
- return (
- <UserItem
- key={user.username}
- user={user}
- onContextMenu={(item) => {
- setDialog(
- item === kChangePermission
- ? {
- type: kChangePermission,
- username: user.username,
- newPermission: !user.administrator,
- }
- : {
- type: item,
- username: user.username,
- }
- );
- }}
- />
- );
- });
-
- return (
- <>
- <Button
- color="success"
- onClick={() =>
- setDialog({
- type: 'create',
- })
- }
- className="align-self-end"
- >
- Create User
- </Button>
- {userComponents}
- {dialogNode}
- </>
- );
- } else {
- return <Spinner />;
- }
-};
-
-export default UserAdmin;
+import React, { useState, useEffect } from "react"; +import { + ListGroupItem, + Row, + Col, + UncontrolledDropdown, + DropdownToggle, + DropdownMenu, + DropdownItem, + Spinner, + Button, +} from "reactstrap"; +import axios from "axios"; + +import OperationDialog from "../common/OperationDialog"; + +import { User, UserWithToken } from "../data/user"; + +const apiBaseUrl = "/api"; + +async function fetchUserList(_token: string): Promise<User[]> { + const res = await axios.get<User[]>(`${apiBaseUrl}/users`); + return res.data; +} + +interface CreateUserInfo { + username: string; + password: string; + administrator: boolean; +} + +async function createUser(user: CreateUserInfo, token: string): Promise<User> { + const res = await axios.post<User>( + `${apiBaseUrl}/userop/createuser?token=${token}`, + user + ); + return res.data; +} + +function deleteUser(username: string, token: string): Promise<void> { + return axios.delete(`${apiBaseUrl}/users/${username}?token=${token}`); +} + +function changeUsername( + oldUsername: string, + newUsername: string, + token: string +): Promise<void> { + return axios.patch(`${apiBaseUrl}/users/${oldUsername}?token=${token}`, { + username: newUsername, + }); +} + +function changePassword( + username: string, + newPassword: string, + token: string +): Promise<void> { + return axios.patch(`${apiBaseUrl}/users/${username}?token=${token}`, { + password: newPassword, + }); +} + +function changePermission( + username: string, + newPermission: boolean, + token: string +): Promise<void> { + return axios.patch(`${apiBaseUrl}/users/${username}?token=${token}`, { + administrator: newPermission, + }); +} + +const kChangeUsername = "changeusername"; +const kChangePassword = "changepassword"; +const kChangePermission = "changepermission"; +const kDelete = "delete"; + +type TChangeUsername = typeof kChangeUsername; +type TChangePassword = typeof kChangePassword; +type TChangePermission = typeof kChangePermission; +type TDelete = typeof kDelete; + +type ContextMenuItem = + | TChangeUsername + | TChangePassword + | TChangePermission + | TDelete; + +interface UserCardProps { + onContextMenu: (item: ContextMenuItem) => void; + user: User; +} + +const UserItem: React.FC<UserCardProps> = (props) => { + const user = props.user; + + const createClickCallback = (item: ContextMenuItem): (() => void) => { + return () => { + props.onContextMenu(item); + }; + }; + + return ( + <ListGroupItem className="container"> + <Row className="align-items-center"> + <Col> + <p className="mb-0 text-primary">{user.username}</p> + <small + className={user.administrator ? "text-danger" : "text-secondary"} + > + {user.administrator ? "administrator" : "user"} + </small> + </Col> + <Col className="col-auto"> + <UncontrolledDropdown> + <DropdownToggle color="warning" className="text-light" caret> + Manage + </DropdownToggle> + <DropdownMenu> + <DropdownItem onClick={createClickCallback(kChangeUsername)}> + Change Username + </DropdownItem> + <DropdownItem onClick={createClickCallback(kChangePassword)}> + Change Password + </DropdownItem> + <DropdownItem onClick={createClickCallback(kChangePermission)}> + Change Permission + </DropdownItem> + <DropdownItem + className="text-danger" + onClick={createClickCallback(kDelete)} + > + Delete + </DropdownItem> + </DropdownMenu> + </UncontrolledDropdown> + </Col> + </Row> + </ListGroupItem> + ); +}; + +interface DialogProps { + open: boolean; + close: () => void; +} + +interface CreateUserDialogProps extends DialogProps { + process: (user: CreateUserInfo) => Promise<void>; +} + +const CreateUserDialog: React.FC<CreateUserDialogProps> = (props) => { + return ( + <OperationDialog + title="Create" + titleColor="create" + inputPrompt="You are creating a new user." + inputScheme={[ + { type: "text", label: "Username" }, + { type: "text", label: "Password" }, + { type: "bool", label: "Administrator" }, + ]} + onProcess={([username, password, administrator]) => + props.process({ + username: username as string, + password: password as string, + administrator: administrator as boolean, + }) + } + close={props.close} + open={props.open} + /> + ); +}; + +const UsernameLabel: React.FC = (props) => { + return <span style={{ color: "blue" }}>{props.children}</span>; +}; + +interface UserDeleteDialogProps extends DialogProps { + username: string; + process: () => Promise<void>; +} + +const UserDeleteDialog: React.FC<UserDeleteDialogProps> = (props) => { + return ( + <OperationDialog + open={props.open} + close={props.close} + title="Dangerous" + titleColor="dangerous" + inputPrompt={() => ( + <> + {"You are deleting user "} + <UsernameLabel>{props.username}</UsernameLabel> + {" !"} + </> + )} + onProcess={props.process} + /> + ); +}; + +interface UserModifyDialogProps<T> extends DialogProps { + username: string; + process: (value: T) => Promise<void>; +} + +const UserChangeUsernameDialog: React.FC<UserModifyDialogProps<string>> = ( + props +) => { + return ( + <OperationDialog + open={props.open} + close={props.close} + title="Caution" + titleColor="dangerous" + inputPrompt={() => ( + <> + {"You are change the username of user "} + <UsernameLabel>{props.username}</UsernameLabel> + {" !"} + </> + )} + inputScheme={[{ type: "text", label: "New Username" }]} + onProcess={([newUsername]) => { + return props.process(newUsername as string); + }} + /> + ); +}; + +const UserChangePasswordDialog: React.FC<UserModifyDialogProps<string>> = ( + props +) => { + return ( + <OperationDialog + open={props.open} + close={props.close} + title="Caution" + titleColor="dangerous" + inputPrompt={() => ( + <> + {"You are change the password of user "} + <UsernameLabel>{props.username}</UsernameLabel> + {" !"} + </> + )} + inputScheme={[{ type: "text", label: "New Password" }]} + onProcess={([newPassword]) => { + return props.process(newPassword as string); + }} + /> + ); +}; + +interface UserChangePermissionDialogProps extends DialogProps { + username: string; + newPermission: boolean; + process: () => Promise<void>; +} + +const UserChangePermissionDialog: React.FC<UserChangePermissionDialogProps> = ( + props +) => { + return ( + <OperationDialog + open={props.open} + close={props.close} + title="Caution" + titleColor="dangerous" + inputPrompt={() => ( + <> + {"You are change user "} + <UsernameLabel>{props.username}</UsernameLabel> + {" to "} + <span style={{ color: "orange" }}> + {props.newPermission ? "administrator" : "normal user"} + </span> + {" !"} + </> + )} + onProcess={props.process} + /> + ); +}; + +interface UserAdminProps { + user: UserWithToken; +} + +const UserAdmin: React.FC<UserAdminProps> = (props) => { + type DialogInfo = + | null + | { + type: "create"; + } + | { type: TDelete; username: string } + | { + type: TChangeUsername; + username: string; + } + | { + type: TChangePassword; + username: string; + } + | { + type: TChangePermission; + username: string; + newPermission: boolean; + }; + + const [users, setUsers] = useState<User[] | null>(null); + const [dialog, setDialog] = useState<DialogInfo>(null); + + const token = props.user.token; + + useEffect(() => { + let subscribe = true; + void fetchUserList(props.user.token).then((us) => { + if (subscribe) { + setUsers(us); + } + }); + return () => { + subscribe = false; + }; + }, [props.user]); + + let dialogNode: React.ReactNode; + if (dialog) + switch (dialog.type) { + case "create": + dialogNode = ( + <CreateUserDialog + open + close={() => setDialog(null)} + process={async (user) => { + const u = await createUser(user, token); + setUsers((oldUsers) => [...(oldUsers ?? []), u]); + }} + /> + ); + break; + case "delete": + dialogNode = ( + <UserDeleteDialog + open + close={() => setDialog(null)} + username={dialog.username} + process={async () => { + await deleteUser(dialog.username, token); + setUsers((oldUsers) => + (oldUsers ?? []).filter((u) => u.username !== dialog.username) + ); + }} + /> + ); + break; + case kChangeUsername: + dialogNode = ( + <UserChangeUsernameDialog + open + close={() => setDialog(null)} + username={dialog.username} + process={async (newUsername) => { + await changeUsername(dialog.username, newUsername, token); + setUsers((oldUsers) => { + const users = (oldUsers ?? []).slice(); + const findedUser = users.find( + (u) => u.username === dialog.username + ); + if (findedUser) findedUser.username = newUsername; + return users; + }); + }} + /> + ); + break; + case kChangePassword: + dialogNode = ( + <UserChangePasswordDialog + open + close={() => setDialog(null)} + username={dialog.username} + process={async (newPassword) => { + await changePassword(dialog.username, newPassword, token); + }} + /> + ); + break; + case kChangePermission: { + const newPermission = dialog.newPermission; + dialogNode = ( + <UserChangePermissionDialog + open + close={() => setDialog(null)} + username={dialog.username} + newPermission={newPermission} + process={async () => { + await changePermission(dialog.username, newPermission, token); + setUsers((oldUsers) => { + const users = (oldUsers ?? []).slice(); + const findedUser = users.find( + (u) => u.username === dialog.username + ); + if (findedUser) findedUser.administrator = newPermission; + return users; + }); + }} + /> + ); + break; + } + } + + if (users) { + const userComponents = users.map((user) => { + return ( + <UserItem + key={user.username} + user={user} + onContextMenu={(item) => { + setDialog( + item === kChangePermission + ? { + type: kChangePermission, + username: user.username, + newPermission: !user.administrator, + } + : { + type: item, + username: user.username, + } + ); + }} + /> + ); + }); + + return ( + <> + <Button + color="success" + onClick={() => + setDialog({ + type: "create", + }) + } + className="align-self-end" + > + Create User + </Button> + {userComponents} + {dialogNode} + </> + ); + } else { + return <Spinner />; + } +}; + +export default UserAdmin; diff --git a/Timeline/ClientApp/src/app/common.ts b/Timeline/ClientApp/src/app/common.ts index 297b4a77..0a2d345f 100644 --- a/Timeline/ClientApp/src/app/common.ts +++ b/Timeline/ClientApp/src/app/common.ts @@ -1,44 +1,44 @@ -import React from 'react';
-import { Observable, Subject } from 'rxjs';
-
-// This error is thrown when ui goes wrong with bad logic.
-// Such as a variable should not be null, but it does.
-// This error should never occur. If it does, it indicates there is some logic bug in codes.
-export class UiLogicError extends Error {}
-
-export function useEventEmiiter(): [() => Observable<null>, () => void] {
- const ref = React.useRef<Subject<null> | null>(null);
-
- return React.useMemo(() => {
- const getter = (): Subject<null> => {
- if (ref.current == null) {
- ref.current = new Subject<null>();
- }
- return ref.current;
- };
- const trigger = (): void => {
- getter().next(null);
- };
- return [getter, trigger];
- }, []);
-}
-
-export function useValueEventEmiiter<T>(): [
- () => Observable<T>,
- (value: T) => void
-] {
- const ref = React.useRef<Subject<T> | null>(null);
-
- return React.useMemo(() => {
- const getter = (): Subject<T> => {
- if (ref.current == null) {
- ref.current = new Subject<T>();
- }
- return ref.current;
- };
- const trigger = (value: T): void => {
- getter().next(value);
- };
- return [getter, trigger];
- }, []);
-}
+import React from "react"; +import { Observable, Subject } from "rxjs"; + +// This error is thrown when ui goes wrong with bad logic. +// Such as a variable should not be null, but it does. +// This error should never occur. If it does, it indicates there is some logic bug in codes. +export class UiLogicError extends Error {} + +export function useEventEmiiter(): [() => Observable<null>, () => void] { + const ref = React.useRef<Subject<null> | null>(null); + + return React.useMemo(() => { + const getter = (): Subject<null> => { + if (ref.current == null) { + ref.current = new Subject<null>(); + } + return ref.current; + }; + const trigger = (): void => { + getter().next(null); + }; + return [getter, trigger]; + }, []); +} + +export function useValueEventEmiiter<T>(): [ + () => Observable<T>, + (value: T) => void +] { + const ref = React.useRef<Subject<T> | null>(null); + + return React.useMemo(() => { + const getter = (): Subject<T> => { + if (ref.current == null) { + ref.current = new Subject<T>(); + } + return ref.current; + }; + const trigger = (value: T): void => { + getter().next(value); + }; + return [getter, trigger]; + }, []); +} diff --git a/Timeline/ClientApp/src/app/common/AlertHost.tsx b/Timeline/ClientApp/src/app/common/AlertHost.tsx index 89831073..e22354fa 100644 --- a/Timeline/ClientApp/src/app/common/AlertHost.tsx +++ b/Timeline/ClientApp/src/app/common/AlertHost.tsx @@ -1,96 +1,96 @@ -import React, { useCallback } from 'react';
-import { Alert } from 'reactstrap';
-import without from 'lodash/without';
-import concat from 'lodash/concat';
-
-import {
- alertService,
- AlertInfoEx,
- kAlertHostId,
- AlertInfo,
-} from './alert-service';
-import { useTranslation } from 'react-i18next';
-
-interface AutoCloseAlertProps {
- alert: AlertInfo;
- close: () => void;
-}
-
-export const AutoCloseAlert: React.FC<AutoCloseAlertProps> = (props) => {
- const { alert } = props;
- const { dismissTime } = alert;
-
- const { t } = useTranslation();
-
- React.useEffect(() => {
- const tag =
- dismissTime === 'never'
- ? null
- : typeof dismissTime === 'number'
- ? window.setTimeout(props.close, dismissTime)
- : window.setTimeout(props.close, 5000);
- return () => {
- if (tag != null) {
- window.clearTimeout(tag);
- }
- };
- }, [dismissTime, props.close]);
-
- return (
- <Alert className="m-3" color={alert.type ?? 'primary'} toggle={props.close}>
- {(() => {
- const { message } = alert;
- if (typeof message === 'function') {
- const Message = message;
- return <Message />;
- } else if (typeof message === 'object' && message.type === 'i18n') {
- return t(message.key);
- } else return alert.message;
- })()}
- </Alert>
- );
-};
-
-// oh what a bad name!
-interface AlertInfoExEx extends AlertInfoEx {
- close: () => void;
-}
-
-export 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
-
- const consume = useCallback((alert: AlertInfoEx): void => {
- const alertEx: AlertInfoExEx = {
- ...alert,
- close: () => {
- setAlerts((oldAlerts) => {
- return without(oldAlerts, alertEx);
- });
- },
- };
- setAlerts((oldAlerts) => {
- return concat(oldAlerts, alertEx);
- });
- }, []);
-
- React.useEffect(() => {
- alertService.registerConsumer(consume);
- return () => {
- alertService.unregisterConsumer(consume);
- };
- }, [consume]);
-
- return (
- <div id={kAlertHostId} className="alert-container">
- {alerts.map((alert) => {
- return (
- <AutoCloseAlert key={alert.id} alert={alert} close={alert.close} />
- );
- })}
- </div>
- );
-};
-
-export default AlertHost;
+import React, { useCallback } from "react"; +import { Alert } from "reactstrap"; +import without from "lodash/without"; +import concat from "lodash/concat"; + +import { + alertService, + AlertInfoEx, + kAlertHostId, + AlertInfo, +} from "./alert-service"; +import { useTranslation } from "react-i18next"; + +interface AutoCloseAlertProps { + alert: AlertInfo; + close: () => void; +} + +export const AutoCloseAlert: React.FC<AutoCloseAlertProps> = (props) => { + const { alert } = props; + const { dismissTime } = alert; + + const { t } = useTranslation(); + + React.useEffect(() => { + const tag = + dismissTime === "never" + ? null + : typeof dismissTime === "number" + ? window.setTimeout(props.close, dismissTime) + : window.setTimeout(props.close, 5000); + return () => { + if (tag != null) { + window.clearTimeout(tag); + } + }; + }, [dismissTime, props.close]); + + return ( + <Alert className="m-3" color={alert.type ?? "primary"} toggle={props.close}> + {(() => { + const { message } = alert; + if (typeof message === "function") { + const Message = message; + return <Message />; + } else if (typeof message === "object" && message.type === "i18n") { + return t(message.key); + } else return alert.message; + })()} + </Alert> + ); +}; + +// oh what a bad name! +interface AlertInfoExEx extends AlertInfoEx { + close: () => void; +} + +export 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 + + const consume = useCallback((alert: AlertInfoEx): void => { + const alertEx: AlertInfoExEx = { + ...alert, + close: () => { + setAlerts((oldAlerts) => { + return without(oldAlerts, alertEx); + }); + }, + }; + setAlerts((oldAlerts) => { + return concat(oldAlerts, alertEx); + }); + }, []); + + React.useEffect(() => { + alertService.registerConsumer(consume); + return () => { + alertService.unregisterConsumer(consume); + }; + }, [consume]); + + return ( + <div id={kAlertHostId} className="alert-container"> + {alerts.map((alert) => { + return ( + <AutoCloseAlert key={alert.id} alert={alert} close={alert.close} /> + ); + })} + </div> + ); +}; + +export default AlertHost; diff --git a/Timeline/ClientApp/src/app/common/AppBar.tsx b/Timeline/ClientApp/src/app/common/AppBar.tsx index 8349aef7..59239696 100644 --- a/Timeline/ClientApp/src/app/common/AppBar.tsx +++ b/Timeline/ClientApp/src/app/common/AppBar.tsx @@ -1,107 +1,107 @@ -import React from 'react';
-import { useHistory, matchPath } from 'react-router';
-import { Link, NavLink } from 'react-router-dom';
-import { Navbar, NavbarToggler, Collapse, Nav, NavItem } from 'reactstrap';
-import { useMediaQuery } from 'react-responsive';
-import { useTranslation } from 'react-i18next';
-
-import { useUser, useAvatar } from '../data/user';
-
-import TimelineLogo from './TimelineLogo';
-import BlobImage from './BlobImage';
-
-const AppBar: React.FC = (_) => {
- const history = useHistory();
- const user = useUser();
- const avatar = useAvatar(user?.username);
-
- const { t } = useTranslation();
-
- const isUpMd = useMediaQuery({
- minWidth: getComputedStyle(document.documentElement).getPropertyValue(
- '--breakpoint-md'
- ),
- });
-
- const [isMenuOpen, setIsMenuOpen] = React.useState(false);
-
- const toggleMenu = React.useCallback((): void => {
- setIsMenuOpen((oldIsMenuOpen) => !oldIsMenuOpen);
- }, []);
-
- const isAdministrator = user && user.administrator;
-
- const rightArea = (
- <div className="ml-auto mr-2">
- {user != null ? (
- <NavLink to={`/users/${user.username}`}>
- <BlobImage
- className="avatar small rounded-circle bg-white"
- blob={avatar}
- />
- </NavLink>
- ) : (
- <NavLink className="text-light" to="/login">
- {t('nav.login')}
- </NavLink>
- )}
- </div>
- );
-
- return (
- <Navbar dark className="fixed-top w-100 bg-primary app-bar" expand="md">
- <Link to="/" className="navbar-brand d-flex align-items-center">
- <TimelineLogo style={{ height: '1em' }} />
- Timeline
- </Link>
-
- {isUpMd ? null : rightArea}
-
- <NavbarToggler onClick={toggleMenu} />
- <Collapse isOpen={isMenuOpen} navbar>
- <Nav className="mr-auto" navbar>
- <NavItem
- className={
- matchPath(history.location.pathname, '/settings')
- ? 'active'
- : undefined
- }
- >
- <NavLink className="nav-link" to="/settings">
- {t('nav.settings')}
- </NavLink>
- </NavItem>
-
- <NavItem
- className={
- matchPath(history.location.pathname, '/about')
- ? 'active'
- : undefined
- }
- >
- <NavLink className="nav-link" to="/about">
- {t('nav.about')}
- </NavLink>
- </NavItem>
-
- {isAdministrator && (
- <NavItem
- className={
- matchPath(history.location.pathname, '/admin')
- ? 'active'
- : undefined
- }
- >
- <NavLink className="nav-link" to="/admin">
- Administration
- </NavLink>
- </NavItem>
- )}
- </Nav>
- {isUpMd ? rightArea : null}
- </Collapse>
- </Navbar>
- );
-};
-
-export default AppBar;
+import React from "react"; +import { useHistory, matchPath } from "react-router"; +import { Link, NavLink } from "react-router-dom"; +import { Navbar, NavbarToggler, Collapse, Nav, NavItem } from "reactstrap"; +import { useMediaQuery } from "react-responsive"; +import { useTranslation } from "react-i18next"; + +import { useUser, useAvatar } from "../data/user"; + +import TimelineLogo from "./TimelineLogo"; +import BlobImage from "./BlobImage"; + +const AppBar: React.FC = (_) => { + const history = useHistory(); + const user = useUser(); + const avatar = useAvatar(user?.username); + + const { t } = useTranslation(); + + const isUpMd = useMediaQuery({ + minWidth: getComputedStyle(document.documentElement).getPropertyValue( + "--breakpoint-md" + ), + }); + + const [isMenuOpen, setIsMenuOpen] = React.useState(false); + + const toggleMenu = React.useCallback((): void => { + setIsMenuOpen((oldIsMenuOpen) => !oldIsMenuOpen); + }, []); + + const isAdministrator = user && user.administrator; + + const rightArea = ( + <div className="ml-auto mr-2"> + {user != null ? ( + <NavLink to={`/users/${user.username}`}> + <BlobImage + className="avatar small rounded-circle bg-white" + blob={avatar} + /> + </NavLink> + ) : ( + <NavLink className="text-light" to="/login"> + {t("nav.login")} + </NavLink> + )} + </div> + ); + + return ( + <Navbar dark className="fixed-top w-100 bg-primary app-bar" expand="md"> + <Link to="/" className="navbar-brand d-flex align-items-center"> + <TimelineLogo style={{ height: "1em" }} /> + Timeline + </Link> + + {isUpMd ? null : rightArea} + + <NavbarToggler onClick={toggleMenu} /> + <Collapse isOpen={isMenuOpen} navbar> + <Nav className="mr-auto" navbar> + <NavItem + className={ + matchPath(history.location.pathname, "/settings") + ? "active" + : undefined + } + > + <NavLink className="nav-link" to="/settings"> + {t("nav.settings")} + </NavLink> + </NavItem> + + <NavItem + className={ + matchPath(history.location.pathname, "/about") + ? "active" + : undefined + } + > + <NavLink className="nav-link" to="/about"> + {t("nav.about")} + </NavLink> + </NavItem> + + {isAdministrator && ( + <NavItem + className={ + matchPath(history.location.pathname, "/admin") + ? "active" + : undefined + } + > + <NavLink className="nav-link" to="/admin"> + Administration + </NavLink> + </NavItem> + )} + </Nav> + {isUpMd ? rightArea : null} + </Collapse> + </Navbar> + ); +}; + +export default AppBar; diff --git a/Timeline/ClientApp/src/app/common/BlobImage.tsx b/Timeline/ClientApp/src/app/common/BlobImage.tsx index 7e5e2447..8602f550 100644 --- a/Timeline/ClientApp/src/app/common/BlobImage.tsx +++ b/Timeline/ClientApp/src/app/common/BlobImage.tsx @@ -1,29 +1,29 @@ -import React from 'react';
-
-import { ExcludeKey } from '../utilities/type';
-
-const BlobImage: React.FC<
- ExcludeKey<React.ImgHTMLAttributes<HTMLImageElement>, 'src'> & {
- blob?: Blob | unknown;
- }
-> = (props) => {
- const { blob, ...otherProps } = props;
-
- const [url, setUrl] = React.useState<string | undefined>(undefined);
-
- React.useEffect(() => {
- if (blob instanceof Blob) {
- const url = URL.createObjectURL(blob);
- setUrl(url);
- return () => {
- URL.revokeObjectURL(url);
- };
- } else {
- setUrl(undefined);
- }
- }, [blob]);
-
- return <img {...otherProps} src={url} />;
-};
-
-export default BlobImage;
+import React from "react"; + +import { ExcludeKey } from "../utilities/type"; + +const BlobImage: React.FC< + ExcludeKey<React.ImgHTMLAttributes<HTMLImageElement>, "src"> & { + blob?: Blob | unknown; + } +> = (props) => { + const { blob, ...otherProps } = props; + + const [url, setUrl] = React.useState<string | undefined>(undefined); + + React.useEffect(() => { + if (blob instanceof Blob) { + const url = URL.createObjectURL(blob); + setUrl(url); + return () => { + URL.revokeObjectURL(url); + }; + } else { + setUrl(undefined); + } + }, [blob]); + + return <img {...otherProps} src={url} />; +}; + +export default BlobImage; diff --git a/Timeline/ClientApp/src/app/common/FileInput.tsx b/Timeline/ClientApp/src/app/common/FileInput.tsx index 94f4aa43..3d1bc2b3 100644 --- a/Timeline/ClientApp/src/app/common/FileInput.tsx +++ b/Timeline/ClientApp/src/app/common/FileInput.tsx @@ -1,41 +1,41 @@ -import React from 'react';
-import clsx from 'clsx';
-
-import { ExcludeKey } from '../utilities/type';
-
-export interface FileInputProps
- extends ExcludeKey<
- React.InputHTMLAttributes<HTMLInputElement>,
- 'type' | 'id'
- > {
- inputId?: string;
- labelText: string;
- color?: string;
- className?: string;
-}
-
-const FileInput: React.FC<FileInputProps> = props => {
- const { inputId, labelText, color, className, ...otherProps } = props;
-
- const realInputId = React.useMemo<string>(() => {
- if (inputId != null) return inputId;
- return (
- 'file-input-' +
- (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
- );
- }, [inputId]);
-
- return (
- <>
- <input className="d-none" type="file" id={realInputId} {...otherProps} />
- <label
- htmlFor={realInputId}
- className={clsx('btn', 'btn-' + (color ?? 'primary'), className)}
- >
- {labelText}
- </label>
- </>
- );
-};
-
-export default FileInput;
+import React from "react"; +import clsx from "clsx"; + +import { ExcludeKey } from "../utilities/type"; + +export interface FileInputProps + extends ExcludeKey< + React.InputHTMLAttributes<HTMLInputElement>, + "type" | "id" + > { + inputId?: string; + labelText: string; + color?: string; + className?: string; +} + +const FileInput: React.FC<FileInputProps> = (props) => { + const { inputId, labelText, color, className, ...otherProps } = props; + + const realInputId = React.useMemo<string>(() => { + if (inputId != null) return inputId; + return ( + "file-input-" + + (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1) + ); + }, [inputId]); + + return ( + <> + <input className="d-none" type="file" id={realInputId} {...otherProps} /> + <label + htmlFor={realInputId} + className={clsx("btn", "btn-" + (color ?? "primary"), className)} + > + {labelText} + </label> + </> + ); +}; + +export default FileInput; diff --git a/Timeline/ClientApp/src/app/common/ImageCropper.tsx b/Timeline/ClientApp/src/app/common/ImageCropper.tsx index fb9bb4f9..cd510969 100644 --- a/Timeline/ClientApp/src/app/common/ImageCropper.tsx +++ b/Timeline/ClientApp/src/app/common/ImageCropper.tsx @@ -1,306 +1,306 @@ -import * as React from 'react';
-import clsx from 'clsx';
-
-import { UiLogicError } from '../common';
-
-export interface Clip {
- left: number;
- top: number;
- width: number;
-}
-
-interface NormailizedClip extends Clip {
- height: number;
-}
-
-interface ImageInfo {
- width: number;
- height: number;
- landscape: boolean;
- ratio: number;
- maxClipWidth: number;
- maxClipHeight: number;
-}
-
-interface ImageCropperSavedState {
- clip: NormailizedClip;
- x: number;
- y: number;
- pointerId: number;
-}
-
-export interface ImageCropperProps {
- clip: Clip | null;
- imageUrl: string;
- onChange: (clip: Clip) => void;
- imageElementCallback?: (element: HTMLImageElement | null) => void;
- className?: string;
-}
-
-const ImageCropper = (props: ImageCropperProps): React.ReactElement => {
- const { clip, imageUrl, onChange, imageElementCallback, className } = props;
-
- const [oldState, setOldState] = React.useState<ImageCropperSavedState | null>(
- null
- );
- const [imageInfo, setImageInfo] = React.useState<ImageInfo | null>(null);
-
- const normalizeClip = (c: Clip | null | undefined): NormailizedClip => {
- if (c == null) {
- return { left: 0, top: 0, width: 0, height: 0 };
- }
-
- return {
- left: c.left || 0,
- top: c.top || 0,
- width: c.width || 0,
- height: imageInfo != null ? (c.width || 0) / imageInfo.ratio : 0,
- };
- };
-
- const c = normalizeClip(clip);
-
- const imgElementRef = React.useRef<HTMLImageElement | null>(null);
-
- const onImageRef = React.useCallback(
- (e: HTMLImageElement | null) => {
- imgElementRef.current = e;
- if (imageElementCallback != null && e == null) {
- imageElementCallback(null);
- }
- },
- [imageElementCallback]
- );
-
- const onImageLoad = React.useCallback(
- (e: React.SyntheticEvent<HTMLImageElement>) => {
- const img = e.currentTarget;
- const landscape = img.naturalWidth >= img.naturalHeight;
-
- const info = {
- width: img.naturalWidth,
- height: img.naturalHeight,
- landscape,
- ratio: img.naturalHeight / img.naturalWidth,
- maxClipWidth: landscape ? img.naturalHeight / img.naturalWidth : 1,
- maxClipHeight: landscape ? 1 : img.naturalWidth / img.naturalHeight,
- };
- setImageInfo(info);
- onChange({ left: 0, top: 0, width: info.maxClipWidth });
- if (imageElementCallback != null) {
- imageElementCallback(img);
- }
- },
- [onChange, imageElementCallback]
- );
-
- const onPointerDown = React.useCallback(
- (e: React.PointerEvent) => {
- if (oldState != null) return;
- e.currentTarget.setPointerCapture(e.pointerId);
- setOldState({
- x: e.clientX,
- y: e.clientY,
- clip: c,
- pointerId: e.pointerId,
- });
- },
- [oldState, c]
- );
-
- const onPointerUp = React.useCallback(
- (e: React.PointerEvent) => {
- if (oldState == null || oldState.pointerId !== e.pointerId) return;
- e.currentTarget.releasePointerCapture(e.pointerId);
- setOldState(null);
- },
- [oldState]
- );
-
- const onPointerMove = React.useCallback(
- (e: React.PointerEvent) => {
- if (oldState == null) return;
-
- const oldClip = oldState.clip;
-
- const movement = { x: e.clientX - oldState.x, y: e.clientY - oldState.y };
-
- const { current: imgElement } = imgElementRef;
-
- if (imgElement == null) throw new UiLogicError('Image element is null.');
-
- const moveRatio = {
- x: movement.x / imgElement.width,
- y: movement.y / imgElement.height,
- };
-
- const newRatio = {
- x: oldClip.left + moveRatio.x,
- y: oldClip.top + moveRatio.y,
- };
- if (newRatio.x < 0) {
- newRatio.x = 0;
- } else if (newRatio.x > 1 - oldClip.width) {
- newRatio.x = 1 - oldClip.width;
- }
- if (newRatio.y < 0) {
- newRatio.y = 0;
- } else if (newRatio.y > 1 - oldClip.height) {
- newRatio.y = 1 - oldClip.height;
- }
-
- onChange({ left: newRatio.x, top: newRatio.y, width: oldClip.width });
- },
- [oldState, onChange]
- );
-
- const onHandlerPointerMove = React.useCallback(
- (e: React.PointerEvent) => {
- if (oldState == null) return;
-
- const oldClip = oldState.clip;
-
- const movement = { x: e.clientX - oldState.x, y: e.clientY - oldState.y };
-
- const ratio = imageInfo == null ? 1 : imageInfo.ratio;
-
- const { current: imgElement } = imgElementRef;
-
- if (imgElement == null) throw new UiLogicError('Image element is null.');
-
- const moveRatio = {
- x: movement.x / imgElement.width,
- y: movement.x / imgElement.width / ratio,
- };
-
- const newRatio = {
- x: oldClip.width + moveRatio.x,
- y: oldClip.height + moveRatio.y,
- };
-
- const maxRatio = {
- x: Math.min(1 - oldClip.left, newRatio.x),
- y: Math.min(1 - oldClip.top, newRatio.y),
- };
-
- const maxWidthRatio = Math.min(maxRatio.x, maxRatio.y * ratio);
-
- let newWidth;
- if (newRatio.x < 0) {
- newWidth = 0;
- } else if (newRatio.x > maxWidthRatio) {
- newWidth = maxWidthRatio;
- } else {
- newWidth = newRatio.x;
- }
-
- onChange({ left: oldClip.left, top: oldClip.top, width: newWidth });
- },
- [imageInfo, oldState, onChange]
- );
-
- const toPercentage = (n: number): string => `${n}%`;
-
- // fuck!!! I just can't find a better way to implement this in pure css
- const containerStyle: React.CSSProperties = (() => {
- if (imageInfo == null) {
- return { width: '100%', paddingTop: '100%', height: 0 };
- } else {
- if (imageInfo.ratio > 1) {
- return {
- width: toPercentage(100 / imageInfo.ratio),
- paddingTop: '100%',
- height: 0,
- };
- } else {
- return {
- width: '100%',
- paddingTop: toPercentage(100 * imageInfo.ratio),
- height: 0,
- };
- }
- }
- })();
-
- return (
- <div
- className={clsx('image-cropper-container', className)}
- style={containerStyle}
- >
- <img ref={onImageRef} src={imageUrl} onLoad={onImageLoad} alt="to crop" />
- <div className="image-cropper-mask-container">
- <div
- className="image-cropper-mask"
- touch-action="none"
- style={{
- left: toPercentage(c.left * 100),
- top: toPercentage(c.top * 100),
- width: toPercentage(c.width * 100),
- height: toPercentage(c.height * 100),
- }}
- onPointerMove={onPointerMove}
- onPointerDown={onPointerDown}
- onPointerUp={onPointerUp}
- />
- </div>
- <div
- className="image-cropper-handler"
- touch-action="none"
- style={{
- left: `calc(${(c.left + c.width) * 100}% - 15px)`,
- top: `calc(${(c.top + c.height) * 100}% - 15px)`,
- }}
- onPointerMove={onHandlerPointerMove}
- onPointerDown={onPointerDown}
- onPointerUp={onPointerUp}
- />
- </div>
- );
-};
-
-export default ImageCropper;
-
-export function applyClipToImage(
- image: HTMLImageElement,
- clip: Clip,
- mimeType: string
-): Promise<Blob> {
- return new Promise((resolve, reject) => {
- const naturalSize = {
- width: image.naturalWidth,
- height: image.naturalHeight,
- };
- const clipArea = {
- x: naturalSize.width * clip.left,
- y: naturalSize.height * clip.top,
- length: naturalSize.width * clip.width,
- };
-
- const canvas = document.createElement('canvas');
- canvas.width = clipArea.length;
- canvas.height = clipArea.length;
- const context = canvas.getContext('2d');
-
- if (context == null) throw new Error('Failed to create context.');
-
- context.drawImage(
- image,
- clipArea.x,
- clipArea.y,
- clipArea.length,
- clipArea.length,
- 0,
- 0,
- clipArea.length,
- clipArea.length
- );
-
- canvas.toBlob((blob) => {
- if (blob == null) {
- reject(new Error('canvas.toBlob returns null'));
- } else {
- resolve(blob);
- }
- }, mimeType);
- });
-}
+import * as React from "react"; +import clsx from "clsx"; + +import { UiLogicError } from "../common"; + +export interface Clip { + left: number; + top: number; + width: number; +} + +interface NormailizedClip extends Clip { + height: number; +} + +interface ImageInfo { + width: number; + height: number; + landscape: boolean; + ratio: number; + maxClipWidth: number; + maxClipHeight: number; +} + +interface ImageCropperSavedState { + clip: NormailizedClip; + x: number; + y: number; + pointerId: number; +} + +export interface ImageCropperProps { + clip: Clip | null; + imageUrl: string; + onChange: (clip: Clip) => void; + imageElementCallback?: (element: HTMLImageElement | null) => void; + className?: string; +} + +const ImageCropper = (props: ImageCropperProps): React.ReactElement => { + const { clip, imageUrl, onChange, imageElementCallback, className } = props; + + const [oldState, setOldState] = React.useState<ImageCropperSavedState | null>( + null + ); + const [imageInfo, setImageInfo] = React.useState<ImageInfo | null>(null); + + const normalizeClip = (c: Clip | null | undefined): NormailizedClip => { + if (c == null) { + return { left: 0, top: 0, width: 0, height: 0 }; + } + + return { + left: c.left || 0, + top: c.top || 0, + width: c.width || 0, + height: imageInfo != null ? (c.width || 0) / imageInfo.ratio : 0, + }; + }; + + const c = normalizeClip(clip); + + const imgElementRef = React.useRef<HTMLImageElement | null>(null); + + const onImageRef = React.useCallback( + (e: HTMLImageElement | null) => { + imgElementRef.current = e; + if (imageElementCallback != null && e == null) { + imageElementCallback(null); + } + }, + [imageElementCallback] + ); + + const onImageLoad = React.useCallback( + (e: React.SyntheticEvent<HTMLImageElement>) => { + const img = e.currentTarget; + const landscape = img.naturalWidth >= img.naturalHeight; + + const info = { + width: img.naturalWidth, + height: img.naturalHeight, + landscape, + ratio: img.naturalHeight / img.naturalWidth, + maxClipWidth: landscape ? img.naturalHeight / img.naturalWidth : 1, + maxClipHeight: landscape ? 1 : img.naturalWidth / img.naturalHeight, + }; + setImageInfo(info); + onChange({ left: 0, top: 0, width: info.maxClipWidth }); + if (imageElementCallback != null) { + imageElementCallback(img); + } + }, + [onChange, imageElementCallback] + ); + + const onPointerDown = React.useCallback( + (e: React.PointerEvent) => { + if (oldState != null) return; + e.currentTarget.setPointerCapture(e.pointerId); + setOldState({ + x: e.clientX, + y: e.clientY, + clip: c, + pointerId: e.pointerId, + }); + }, + [oldState, c] + ); + + const onPointerUp = React.useCallback( + (e: React.PointerEvent) => { + if (oldState == null || oldState.pointerId !== e.pointerId) return; + e.currentTarget.releasePointerCapture(e.pointerId); + setOldState(null); + }, + [oldState] + ); + + const onPointerMove = React.useCallback( + (e: React.PointerEvent) => { + if (oldState == null) return; + + const oldClip = oldState.clip; + + const movement = { x: e.clientX - oldState.x, y: e.clientY - oldState.y }; + + const { current: imgElement } = imgElementRef; + + if (imgElement == null) throw new UiLogicError("Image element is null."); + + const moveRatio = { + x: movement.x / imgElement.width, + y: movement.y / imgElement.height, + }; + + const newRatio = { + x: oldClip.left + moveRatio.x, + y: oldClip.top + moveRatio.y, + }; + if (newRatio.x < 0) { + newRatio.x = 0; + } else if (newRatio.x > 1 - oldClip.width) { + newRatio.x = 1 - oldClip.width; + } + if (newRatio.y < 0) { + newRatio.y = 0; + } else if (newRatio.y > 1 - oldClip.height) { + newRatio.y = 1 - oldClip.height; + } + + onChange({ left: newRatio.x, top: newRatio.y, width: oldClip.width }); + }, + [oldState, onChange] + ); + + const onHandlerPointerMove = React.useCallback( + (e: React.PointerEvent) => { + if (oldState == null) return; + + const oldClip = oldState.clip; + + const movement = { x: e.clientX - oldState.x, y: e.clientY - oldState.y }; + + const ratio = imageInfo == null ? 1 : imageInfo.ratio; + + const { current: imgElement } = imgElementRef; + + if (imgElement == null) throw new UiLogicError("Image element is null."); + + const moveRatio = { + x: movement.x / imgElement.width, + y: movement.x / imgElement.width / ratio, + }; + + const newRatio = { + x: oldClip.width + moveRatio.x, + y: oldClip.height + moveRatio.y, + }; + + const maxRatio = { + x: Math.min(1 - oldClip.left, newRatio.x), + y: Math.min(1 - oldClip.top, newRatio.y), + }; + + const maxWidthRatio = Math.min(maxRatio.x, maxRatio.y * ratio); + + let newWidth; + if (newRatio.x < 0) { + newWidth = 0; + } else if (newRatio.x > maxWidthRatio) { + newWidth = maxWidthRatio; + } else { + newWidth = newRatio.x; + } + + onChange({ left: oldClip.left, top: oldClip.top, width: newWidth }); + }, + [imageInfo, oldState, onChange] + ); + + const toPercentage = (n: number): string => `${n}%`; + + // fuck!!! I just can't find a better way to implement this in pure css + const containerStyle: React.CSSProperties = (() => { + if (imageInfo == null) { + return { width: "100%", paddingTop: "100%", height: 0 }; + } else { + if (imageInfo.ratio > 1) { + return { + width: toPercentage(100 / imageInfo.ratio), + paddingTop: "100%", + height: 0, + }; + } else { + return { + width: "100%", + paddingTop: toPercentage(100 * imageInfo.ratio), + height: 0, + }; + } + } + })(); + + return ( + <div + className={clsx("image-cropper-container", className)} + style={containerStyle} + > + <img ref={onImageRef} src={imageUrl} onLoad={onImageLoad} alt="to crop" /> + <div className="image-cropper-mask-container"> + <div + className="image-cropper-mask" + touch-action="none" + style={{ + left: toPercentage(c.left * 100), + top: toPercentage(c.top * 100), + width: toPercentage(c.width * 100), + height: toPercentage(c.height * 100), + }} + onPointerMove={onPointerMove} + onPointerDown={onPointerDown} + onPointerUp={onPointerUp} + /> + </div> + <div + className="image-cropper-handler" + touch-action="none" + style={{ + left: `calc(${(c.left + c.width) * 100}% - 15px)`, + top: `calc(${(c.top + c.height) * 100}% - 15px)`, + }} + onPointerMove={onHandlerPointerMove} + onPointerDown={onPointerDown} + onPointerUp={onPointerUp} + /> + </div> + ); +}; + +export default ImageCropper; + +export function applyClipToImage( + image: HTMLImageElement, + clip: Clip, + mimeType: string +): Promise<Blob> { + return new Promise((resolve, reject) => { + const naturalSize = { + width: image.naturalWidth, + height: image.naturalHeight, + }; + const clipArea = { + x: naturalSize.width * clip.left, + y: naturalSize.height * clip.top, + length: naturalSize.width * clip.width, + }; + + const canvas = document.createElement("canvas"); + canvas.width = clipArea.length; + canvas.height = clipArea.length; + const context = canvas.getContext("2d"); + + if (context == null) throw new Error("Failed to create context."); + + context.drawImage( + image, + clipArea.x, + clipArea.y, + clipArea.length, + clipArea.length, + 0, + 0, + clipArea.length, + clipArea.length + ); + + canvas.toBlob((blob) => { + if (blob == null) { + reject(new Error("canvas.toBlob returns null")); + } else { + resolve(blob); + } + }, mimeType); + }); +} diff --git a/Timeline/ClientApp/src/app/common/LoadingPage.tsx b/Timeline/ClientApp/src/app/common/LoadingPage.tsx index c1bc7105..a849126d 100644 --- a/Timeline/ClientApp/src/app/common/LoadingPage.tsx +++ b/Timeline/ClientApp/src/app/common/LoadingPage.tsx @@ -1,12 +1,12 @@ -import React from 'react';
-import { Spinner } from 'reactstrap';
-
-const LoadingPage: React.FC = () => {
- return (
- <div className="position-fixed w-100 h-100 d-flex justify-content-center align-items-center">
- <Spinner style={{ height: '2.5rem', width: '2.5rem' }} color="primary" />
- </div>
- );
-};
-
-export default LoadingPage;
+import React from "react"; +import { Spinner } from "reactstrap"; + +const LoadingPage: React.FC = () => { + return ( + <div className="position-fixed w-100 h-100 d-flex justify-content-center align-items-center"> + <Spinner style={{ height: "2.5rem", width: "2.5rem" }} color="primary" /> + </div> + ); +}; + +export default LoadingPage; diff --git a/Timeline/ClientApp/src/app/common/OperationDialog.tsx b/Timeline/ClientApp/src/app/common/OperationDialog.tsx index 501a353e..bca4580c 100644 --- a/Timeline/ClientApp/src/app/common/OperationDialog.tsx +++ b/Timeline/ClientApp/src/app/common/OperationDialog.tsx @@ -1,381 +1,381 @@ -import React, { useState } from 'react';
-import { useTranslation } from 'react-i18next';
-import {
- Spinner,
- Container,
- ModalBody,
- Label,
- Input,
- FormGroup,
- FormFeedback,
- ModalFooter,
- Button,
- Modal,
- ModalHeader,
- FormText,
-} from 'reactstrap';
-
-import { UiLogicError } from '../common';
-
-const DefaultProcessPrompt: React.FC = (_) => {
- return (
- <Container className="justify-content-center align-items-center">
- <Spinner />
- </Container>
- );
-};
-
-interface DefaultErrorPromptProps {
- error?: string;
-}
-
-const DefaultErrorPrompt: React.FC<DefaultErrorPromptProps> = (props) => {
- const { t } = useTranslation();
-
- let result = <p className="text-danger">{t('operationDialog.error')}</p>;
-
- if (props.error != null) {
- result = (
- <>
- {result}
- <p className="text-danger">{props.error}</p>
- </>
- );
- }
-
- return result;
-};
-
-export type OperationInputOptionalError = undefined | null | string;
-
-export interface OperationInputErrorInfo {
- [index: number]: OperationInputOptionalError;
-}
-
-export type OperationInputValidator<TValue> = (
- value: TValue,
- values: (string | boolean)[]
-) => OperationInputOptionalError | OperationInputErrorInfo;
-
-export interface OperationTextInputInfo {
- type: 'text';
- password?: boolean;
- label?: string;
- initValue?: string;
- textFieldProps?: Omit<
- React.InputHTMLAttributes<HTMLInputElement>,
- 'type' | 'value' | 'onChange'
- >;
- helperText?: string;
- validator?: OperationInputValidator<string>;
-}
-
-export interface OperationBoolInputInfo {
- type: 'bool';
- label: string;
- initValue?: boolean;
-}
-
-export interface OperationSelectInputInfoOption {
- value: string;
- label: string;
- icon?: React.ReactElement;
-}
-
-export interface OperationSelectInputInfo {
- type: 'select';
- label: string;
- options: OperationSelectInputInfoOption[];
- initValue?: string;
-}
-
-export type OperationInputInfo =
- | OperationTextInputInfo
- | OperationBoolInputInfo
- | OperationSelectInputInfo;
-
-interface OperationResult {
- type: 'success' | 'failure';
- data: unknown;
-}
-
-interface OperationDialogProps {
- open: boolean;
- close: () => void;
- title: React.ReactNode;
- titleColor?: 'default' | 'dangerous' | 'create' | string;
- onProcess: (inputs: (string | boolean)[]) => Promise<unknown>;
- inputScheme?: OperationInputInfo[];
- inputPrompt?: string | (() => React.ReactNode);
- processPrompt?: () => React.ReactNode;
- successPrompt?: (data: unknown) => React.ReactNode;
- failurePrompt?: (error: unknown) => React.ReactNode;
- onSuccessAndClose?: () => void;
-}
-
-const OperationDialog: React.FC<OperationDialogProps> = (props) => {
- const inputScheme = props.inputScheme ?? [];
-
- const { t } = useTranslation();
-
- type Step = 'input' | 'process' | OperationResult;
- const [step, setStep] = useState<Step>('input');
- const [values, setValues] = useState<(boolean | string)[]>(
- inputScheme.map((i) => {
- if (i.type === 'bool') {
- return i.initValue ?? false;
- } else if (i.type === 'text' || i.type === 'select') {
- return i.initValue ?? '';
- } else {
- throw new UiLogicError('Unknown input scheme.');
- }
- })
- );
- const [inputError, setInputError] = useState<OperationInputErrorInfo>({});
-
- const close = (): void => {
- if (step !== 'process') {
- props.close();
- if (
- typeof step === 'object' &&
- step.type === 'success' &&
- props.onSuccessAndClose
- ) {
- props.onSuccessAndClose();
- }
- } else {
- console.log('Attempt to close modal when processing.');
- }
- };
-
- const onConfirm = (): void => {
- setStep('process');
- props.onProcess(values).then(
- (d: unknown) => {
- setStep({
- type: 'success',
- data: d,
- });
- },
- (e: unknown) => {
- setStep({
- type: 'failure',
- data: e,
- });
- }
- );
- };
-
- let body: React.ReactNode;
- if (step === 'input') {
- let inputPrompt =
- typeof props.inputPrompt === 'function'
- ? props.inputPrompt()
- : props.inputPrompt;
- inputPrompt = <h6>{inputPrompt}</h6>;
-
- const updateValue = (
- index: number,
- newValue: string | boolean
- ): (string | boolean)[] => {
- const oldValues = values;
- const newValues = oldValues.slice();
- newValues[index] = newValue;
- setValues(newValues);
- return newValues;
- };
-
- const testErrorInfo = (errorInfo: OperationInputErrorInfo): boolean => {
- for (let i = 0; i < inputScheme.length; i++) {
- if (inputScheme[i].type === 'text' && errorInfo[i] != null) {
- return true;
- }
- }
- return false;
- };
-
- const calculateError = (
- oldError: OperationInputErrorInfo,
- index: number,
- newError: OperationInputOptionalError | OperationInputErrorInfo
- ): OperationInputErrorInfo => {
- if (newError === undefined) {
- return oldError;
- } else if (newError === null || typeof newError === 'string') {
- return { ...oldError, [index]: newError };
- } else {
- const newInputError: OperationInputErrorInfo = { ...oldError };
- for (const [index, error] of Object.entries(newError)) {
- if (error !== undefined) {
- newInputError[+index] = error as OperationInputOptionalError;
- }
- }
- return newInputError;
- }
- };
-
- const validateAll = (): boolean => {
- let newInputError = inputError;
- for (let i = 0; i < inputScheme.length; i++) {
- const item = inputScheme[i];
- if (item.type === 'text') {
- newInputError = calculateError(
- newInputError,
- i,
- item.validator?.(values[i] as string, values)
- );
- }
- }
- const result = !testErrorInfo(newInputError);
- setInputError(newInputError);
- return result;
- };
-
- body = (
- <>
- <ModalBody>
- {inputPrompt}
- {inputScheme.map((item, index) => {
- const value = values[index];
- const error: string | undefined = ((e) =>
- typeof e === 'string' ? t(e) : undefined)(inputError?.[index]);
-
- if (item.type === 'text') {
- return (
- <FormGroup key={index}>
- {item.label && <Label>{t(item.label)}</Label>}
- <Input
- type={item.password === true ? 'password' : 'text'}
- value={value as string}
- onChange={(e) => {
- const v = e.target.value;
- const newValues = updateValue(index, v);
- setInputError(
- calculateError(
- inputError,
- index,
- item.validator?.(v, newValues)
- )
- );
- }}
- invalid={error != null}
- {...item.textFieldProps}
- />
- {error != null && <FormFeedback>{error}</FormFeedback>}
- {item.helperText && <FormText>{t(item.helperText)}</FormText>}
- </FormGroup>
- );
- } else if (item.type === 'bool') {
- return (
- <FormGroup check key={index}>
- <Input
- type="checkbox"
- value={value as string}
- onChange={(e) => {
- updateValue(
- index,
- (e.target as HTMLInputElement).checked
- );
- }}
- />
- <Label check>{t(item.label)}</Label>
- </FormGroup>
- );
- } else if (item.type === 'select') {
- return (
- <FormGroup key={index}>
- <Label>{t(item.label)}</Label>
- <Input
- type="select"
- value={value as string}
- onChange={(event) => {
- updateValue(index, event.target.value);
- }}
- >
- {item.options.map((option, i) => {
- return (
- <option value={option.value} key={i}>
- {option.icon}
- {t(option.label)}
- </option>
- );
- })}
- </Input>
- </FormGroup>
- );
- }
- })}
- </ModalBody>
- <ModalFooter>
- <Button color="secondary" onClick={close}>
- {t('operationDialog.cancel')}
- </Button>
- <Button
- color="primary"
- disabled={testErrorInfo(inputError)}
- onClick={() => {
- if (validateAll()) {
- onConfirm();
- }
- }}
- >
- {t('operationDialog.confirm')}
- </Button>
- </ModalFooter>
- </>
- );
- } else if (step === 'process') {
- body = (
- <ModalBody>
- {props.processPrompt?.() ?? <DefaultProcessPrompt />}
- </ModalBody>
- );
- } else {
- let content: React.ReactNode;
- const result = step;
- if (result.type === 'success') {
- content =
- props.successPrompt?.(result.data) ?? t('operationDialog.success');
- if (typeof content === 'string')
- content = <p className="text-success">{content}</p>;
- } else {
- content = props.failurePrompt?.(result.data) ?? <DefaultErrorPrompt />;
- if (typeof content === 'string')
- content = <DefaultErrorPrompt error={content} />;
- }
- body = (
- <>
- <ModalBody>{content}</ModalBody>
- <ModalFooter>
- <Button color="primary" onClick={close}>
- {t('operationDialog.ok')}
- </Button>
- </ModalFooter>
- </>
- );
- }
-
- const title = typeof props.title === 'string' ? t(props.title) : props.title;
-
- return (
- <Modal isOpen={props.open} toggle={close}>
- <ModalHeader
- className={
- props.titleColor != null
- ? 'text-' +
- (props.titleColor === 'create'
- ? 'success'
- : props.titleColor === 'dangerous'
- ? 'danger'
- : props.titleColor)
- : undefined
- }
- >
- {title}
- </ModalHeader>
- {body}
- </Modal>
- );
-};
-
-export default OperationDialog;
+import React, { useState } from "react"; +import { useTranslation } from "react-i18next"; +import { + Spinner, + Container, + ModalBody, + Label, + Input, + FormGroup, + FormFeedback, + ModalFooter, + Button, + Modal, + ModalHeader, + FormText, +} from "reactstrap"; + +import { UiLogicError } from "../common"; + +const DefaultProcessPrompt: React.FC = (_) => { + return ( + <Container className="justify-content-center align-items-center"> + <Spinner /> + </Container> + ); +}; + +interface DefaultErrorPromptProps { + error?: string; +} + +const DefaultErrorPrompt: React.FC<DefaultErrorPromptProps> = (props) => { + const { t } = useTranslation(); + + let result = <p className="text-danger">{t("operationDialog.error")}</p>; + + if (props.error != null) { + result = ( + <> + {result} + <p className="text-danger">{props.error}</p> + </> + ); + } + + return result; +}; + +export type OperationInputOptionalError = undefined | null | string; + +export interface OperationInputErrorInfo { + [index: number]: OperationInputOptionalError; +} + +export type OperationInputValidator<TValue> = ( + value: TValue, + values: (string | boolean)[] +) => OperationInputOptionalError | OperationInputErrorInfo; + +export interface OperationTextInputInfo { + type: "text"; + password?: boolean; + label?: string; + initValue?: string; + textFieldProps?: Omit< + React.InputHTMLAttributes<HTMLInputElement>, + "type" | "value" | "onChange" + >; + helperText?: string; + validator?: OperationInputValidator<string>; +} + +export interface OperationBoolInputInfo { + type: "bool"; + label: string; + initValue?: boolean; +} + +export interface OperationSelectInputInfoOption { + value: string; + label: string; + icon?: React.ReactElement; +} + +export interface OperationSelectInputInfo { + type: "select"; + label: string; + options: OperationSelectInputInfoOption[]; + initValue?: string; +} + +export type OperationInputInfo = + | OperationTextInputInfo + | OperationBoolInputInfo + | OperationSelectInputInfo; + +interface OperationResult { + type: "success" | "failure"; + data: unknown; +} + +interface OperationDialogProps { + open: boolean; + close: () => void; + title: React.ReactNode; + titleColor?: "default" | "dangerous" | "create" | string; + onProcess: (inputs: (string | boolean)[]) => Promise<unknown>; + inputScheme?: OperationInputInfo[]; + inputPrompt?: string | (() => React.ReactNode); + processPrompt?: () => React.ReactNode; + successPrompt?: (data: unknown) => React.ReactNode; + failurePrompt?: (error: unknown) => React.ReactNode; + onSuccessAndClose?: () => void; +} + +const OperationDialog: React.FC<OperationDialogProps> = (props) => { + const inputScheme = props.inputScheme ?? []; + + const { t } = useTranslation(); + + type Step = "input" | "process" | OperationResult; + const [step, setStep] = useState<Step>("input"); + const [values, setValues] = useState<(boolean | string)[]>( + inputScheme.map((i) => { + if (i.type === "bool") { + return i.initValue ?? false; + } else if (i.type === "text" || i.type === "select") { + return i.initValue ?? ""; + } else { + throw new UiLogicError("Unknown input scheme."); + } + }) + ); + const [inputError, setInputError] = useState<OperationInputErrorInfo>({}); + + const close = (): void => { + if (step !== "process") { + props.close(); + if ( + typeof step === "object" && + step.type === "success" && + props.onSuccessAndClose + ) { + props.onSuccessAndClose(); + } + } else { + console.log("Attempt to close modal when processing."); + } + }; + + const onConfirm = (): void => { + setStep("process"); + props.onProcess(values).then( + (d: unknown) => { + setStep({ + type: "success", + data: d, + }); + }, + (e: unknown) => { + setStep({ + type: "failure", + data: e, + }); + } + ); + }; + + let body: React.ReactNode; + if (step === "input") { + let inputPrompt = + typeof props.inputPrompt === "function" + ? props.inputPrompt() + : props.inputPrompt; + inputPrompt = <h6>{inputPrompt}</h6>; + + const updateValue = ( + index: number, + newValue: string | boolean + ): (string | boolean)[] => { + const oldValues = values; + const newValues = oldValues.slice(); + newValues[index] = newValue; + setValues(newValues); + return newValues; + }; + + const testErrorInfo = (errorInfo: OperationInputErrorInfo): boolean => { + for (let i = 0; i < inputScheme.length; i++) { + if (inputScheme[i].type === "text" && errorInfo[i] != null) { + return true; + } + } + return false; + }; + + const calculateError = ( + oldError: OperationInputErrorInfo, + index: number, + newError: OperationInputOptionalError | OperationInputErrorInfo + ): OperationInputErrorInfo => { + if (newError === undefined) { + return oldError; + } else if (newError === null || typeof newError === "string") { + return { ...oldError, [index]: newError }; + } else { + const newInputError: OperationInputErrorInfo = { ...oldError }; + for (const [index, error] of Object.entries(newError)) { + if (error !== undefined) { + newInputError[+index] = error as OperationInputOptionalError; + } + } + return newInputError; + } + }; + + const validateAll = (): boolean => { + let newInputError = inputError; + for (let i = 0; i < inputScheme.length; i++) { + const item = inputScheme[i]; + if (item.type === "text") { + newInputError = calculateError( + newInputError, + i, + item.validator?.(values[i] as string, values) + ); + } + } + const result = !testErrorInfo(newInputError); + setInputError(newInputError); + return result; + }; + + body = ( + <> + <ModalBody> + {inputPrompt} + {inputScheme.map((item, index) => { + const value = values[index]; + const error: string | undefined = ((e) => + typeof e === "string" ? t(e) : undefined)(inputError?.[index]); + + if (item.type === "text") { + return ( + <FormGroup key={index}> + {item.label && <Label>{t(item.label)}</Label>} + <Input + type={item.password === true ? "password" : "text"} + value={value as string} + onChange={(e) => { + const v = e.target.value; + const newValues = updateValue(index, v); + setInputError( + calculateError( + inputError, + index, + item.validator?.(v, newValues) + ) + ); + }} + invalid={error != null} + {...item.textFieldProps} + /> + {error != null && <FormFeedback>{error}</FormFeedback>} + {item.helperText && <FormText>{t(item.helperText)}</FormText>} + </FormGroup> + ); + } else if (item.type === "bool") { + return ( + <FormGroup check key={index}> + <Input + type="checkbox" + value={value as string} + onChange={(e) => { + updateValue( + index, + (e.target as HTMLInputElement).checked + ); + }} + /> + <Label check>{t(item.label)}</Label> + </FormGroup> + ); + } else if (item.type === "select") { + return ( + <FormGroup key={index}> + <Label>{t(item.label)}</Label> + <Input + type="select" + value={value as string} + onChange={(event) => { + updateValue(index, event.target.value); + }} + > + {item.options.map((option, i) => { + return ( + <option value={option.value} key={i}> + {option.icon} + {t(option.label)} + </option> + ); + })} + </Input> + </FormGroup> + ); + } + })} + </ModalBody> + <ModalFooter> + <Button color="secondary" onClick={close}> + {t("operationDialog.cancel")} + </Button> + <Button + color="primary" + disabled={testErrorInfo(inputError)} + onClick={() => { + if (validateAll()) { + onConfirm(); + } + }} + > + {t("operationDialog.confirm")} + </Button> + </ModalFooter> + </> + ); + } else if (step === "process") { + body = ( + <ModalBody> + {props.processPrompt?.() ?? <DefaultProcessPrompt />} + </ModalBody> + ); + } else { + let content: React.ReactNode; + const result = step; + if (result.type === "success") { + content = + props.successPrompt?.(result.data) ?? t("operationDialog.success"); + if (typeof content === "string") + content = <p className="text-success">{content}</p>; + } else { + content = props.failurePrompt?.(result.data) ?? <DefaultErrorPrompt />; + if (typeof content === "string") + content = <DefaultErrorPrompt error={content} />; + } + body = ( + <> + <ModalBody>{content}</ModalBody> + <ModalFooter> + <Button color="primary" onClick={close}> + {t("operationDialog.ok")} + </Button> + </ModalFooter> + </> + ); + } + + const title = typeof props.title === "string" ? t(props.title) : props.title; + + return ( + <Modal isOpen={props.open} toggle={close}> + <ModalHeader + className={ + props.titleColor != null + ? "text-" + + (props.titleColor === "create" + ? "success" + : props.titleColor === "dangerous" + ? "danger" + : props.titleColor) + : undefined + } + > + {title} + </ModalHeader> + {body} + </Modal> + ); +}; + +export default OperationDialog; diff --git a/Timeline/ClientApp/src/app/common/SearchInput.tsx b/Timeline/ClientApp/src/app/common/SearchInput.tsx index 46fb00d1..5a0b0eaa 100644 --- a/Timeline/ClientApp/src/app/common/SearchInput.tsx +++ b/Timeline/ClientApp/src/app/common/SearchInput.tsx @@ -1,63 +1,63 @@ -import React, { useCallback } from 'react';
-import clsx from 'clsx';
-import { Spinner, Input, Button } from 'reactstrap';
-import { useTranslation } from 'react-i18next';
-
-export interface SearchInputProps {
- value: string;
- onChange: (value: string) => void;
- onButtonClick: () => void;
- className?: string;
- loading?: boolean;
- buttonText?: string;
- placeholder?: string;
- additionalButton?: React.ReactNode;
-}
-
-const SearchInput: React.FC<SearchInputProps> = (props) => {
- const { onChange, onButtonClick } = props;
-
- const { t } = useTranslation();
-
- const onInputChange = useCallback(
- (event: React.ChangeEvent<HTMLInputElement>): void => {
- onChange(event.currentTarget.value);
- },
- [onChange]
- );
-
- const onInputKeyPress = useCallback(
- (event: React.KeyboardEvent<HTMLInputElement>): void => {
- if (event.key === 'Enter') {
- onButtonClick();
- }
- },
- [onButtonClick]
- );
-
- return (
- <div className={clsx('form-inline my-2', props.className)}>
- <Input
- className="mr-sm-2"
- value={props.value}
- onChange={onInputChange}
- onKeyPress={onInputKeyPress}
- placeholder={props.placeholder}
- />
- <div className="mt-2 mt-sm-0 order-sm-last ml-sm-3">
- {props.additionalButton}
- </div>
- <div className="mt-2 mt-sm-0 ml-auto ml-sm-0">
- {props.loading ? (
- <Spinner />
- ) : (
- <Button outline color="primary" onClick={props.onButtonClick}>
- {props.buttonText ?? t('search')}
- </Button>
- )}
- </div>
- </div>
- );
-};
-
-export default SearchInput;
+import React, { useCallback } from "react"; +import clsx from "clsx"; +import { Spinner, Input, Button } from "reactstrap"; +import { useTranslation } from "react-i18next"; + +export interface SearchInputProps { + value: string; + onChange: (value: string) => void; + onButtonClick: () => void; + className?: string; + loading?: boolean; + buttonText?: string; + placeholder?: string; + additionalButton?: React.ReactNode; +} + +const SearchInput: React.FC<SearchInputProps> = (props) => { + const { onChange, onButtonClick } = props; + + const { t } = useTranslation(); + + const onInputChange = useCallback( + (event: React.ChangeEvent<HTMLInputElement>): void => { + onChange(event.currentTarget.value); + }, + [onChange] + ); + + const onInputKeyPress = useCallback( + (event: React.KeyboardEvent<HTMLInputElement>): void => { + if (event.key === "Enter") { + onButtonClick(); + } + }, + [onButtonClick] + ); + + return ( + <div className={clsx("form-inline my-2", props.className)}> + <Input + className="mr-sm-2" + value={props.value} + onChange={onInputChange} + onKeyPress={onInputKeyPress} + placeholder={props.placeholder} + /> + <div className="mt-2 mt-sm-0 order-sm-last ml-sm-3"> + {props.additionalButton} + </div> + <div className="mt-2 mt-sm-0 ml-auto ml-sm-0"> + {props.loading ? ( + <Spinner /> + ) : ( + <Button outline color="primary" onClick={props.onButtonClick}> + {props.buttonText ?? t("search")} + </Button> + )} + </div> + </div> + ); +}; + +export default SearchInput; diff --git a/Timeline/ClientApp/src/app/common/TimelineLogo.tsx b/Timeline/ClientApp/src/app/common/TimelineLogo.tsx index 1ec62021..27d188fc 100644 --- a/Timeline/ClientApp/src/app/common/TimelineLogo.tsx +++ b/Timeline/ClientApp/src/app/common/TimelineLogo.tsx @@ -1,26 +1,26 @@ -import React, { SVGAttributes } from 'react';
-
-export interface TimelineLogoProps extends SVGAttributes<SVGElement> {
- color?: string;
-}
-
-const TimelineLogo: React.FC<TimelineLogoProps> = props => {
- const { color, ...forwardProps } = props;
- const coercedColor = color ?? 'currentcolor';
- return (
- <svg
- className={props.className}
- viewBox="0 0 100 100"
- fill="none"
- strokeWidth="12"
- stroke={coercedColor}
- {...forwardProps}
- >
- <line x1="50" y1="0" x2="50" y2="25" />
- <circle cx="50" cy="50" r="22" />
- <line x1="50" y1="75" x2="50" y2="100" />
- </svg>
- );
-};
-
-export default TimelineLogo;
+import React, { SVGAttributes } from "react"; + +export interface TimelineLogoProps extends SVGAttributes<SVGElement> { + color?: string; +} + +const TimelineLogo: React.FC<TimelineLogoProps> = (props) => { + const { color, ...forwardProps } = props; + const coercedColor = color ?? "currentcolor"; + return ( + <svg + className={props.className} + viewBox="0 0 100 100" + fill="none" + strokeWidth="12" + stroke={coercedColor} + {...forwardProps} + > + <line x1="50" y1="0" x2="50" y2="25" /> + <circle cx="50" cy="50" r="22" /> + <line x1="50" y1="75" x2="50" y2="100" /> + </svg> + ); +}; + +export default TimelineLogo; diff --git a/Timeline/ClientApp/src/app/common/UserTimelineLogo.tsx b/Timeline/ClientApp/src/app/common/UserTimelineLogo.tsx index 3b721985..29f6a69f 100644 --- a/Timeline/ClientApp/src/app/common/UserTimelineLogo.tsx +++ b/Timeline/ClientApp/src/app/common/UserTimelineLogo.tsx @@ -1,26 +1,26 @@ -import React, { SVGAttributes } from 'react';
-
-export interface UserTimelineLogoProps extends SVGAttributes<SVGElement> {
- color?: string;
-}
-
-const UserTimelineLogo: React.FC<UserTimelineLogoProps> = props => {
- const { color, ...forwardProps } = props;
- const coercedColor = color ?? 'currentcolor';
-
- return (
- <svg viewBox="0 0 100 100" {...forwardProps}>
- <g fill="none" stroke={coercedColor} strokeWidth="12">
- <line x1="50" x2="50" y1="0" y2="25" />
- <circle cx="50" cy="50" r="22" />
- <line x1="50" x2="50" y1="75" y2="100" />
- </g>
- <g fill={color}>
- <circle cx="85" cy="75" r="10" />
- <path d="m70,100c0,0 15,-30 30,0.25" />
- </g>
- </svg>
- );
-};
-
-export default UserTimelineLogo;
+import React, { SVGAttributes } from "react"; + +export interface UserTimelineLogoProps extends SVGAttributes<SVGElement> { + color?: string; +} + +const UserTimelineLogo: React.FC<UserTimelineLogoProps> = (props) => { + const { color, ...forwardProps } = props; + const coercedColor = color ?? "currentcolor"; + + return ( + <svg viewBox="0 0 100 100" {...forwardProps}> + <g fill="none" stroke={coercedColor} strokeWidth="12"> + <line x1="50" x2="50" y1="0" y2="25" /> + <circle cx="50" cy="50" r="22" /> + <line x1="50" x2="50" y1="75" y2="100" /> + </g> + <g fill={color}> + <circle cx="85" cy="75" r="10" /> + <path d="m70,100c0,0 15,-30 30,0.25" /> + </g> + </svg> + ); +}; + +export default UserTimelineLogo; diff --git a/Timeline/ClientApp/src/app/common/alert-service.ts b/Timeline/ClientApp/src/app/common/alert-service.ts index 957c5e10..e4c0e653 100644 --- a/Timeline/ClientApp/src/app/common/alert-service.ts +++ b/Timeline/ClientApp/src/app/common/alert-service.ts @@ -1,61 +1,61 @@ -import React from 'react';
-import pull from 'lodash/pull';
-
-export interface AlertInfo {
- type?: 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info';
- message: string | React.FC<unknown> | { type: 'i18n'; key: string };
- dismissTime?: number | 'never';
-}
-
-export interface AlertInfoEx extends AlertInfo {
- id: number;
-}
-
-export type AlertConsumer = (alerts: AlertInfoEx) => void;
-
-export class AlertService {
- private consumers: AlertConsumer[] = [];
- private savedAlerts: AlertInfoEx[] = [];
- private currentId = 1;
-
- private produce(alert: AlertInfoEx): void {
- for (const consumer of this.consumers) {
- consumer(alert);
- }
- }
-
- registerConsumer(consumer: AlertConsumer): void {
- this.consumers.push(consumer);
- if (this.savedAlerts.length !== 0) {
- for (const alert of this.savedAlerts) {
- this.produce(alert);
- }
- this.savedAlerts = [];
- }
- }
-
- unregisterConsumer(consumer: AlertConsumer): void {
- pull(this.consumers, consumer);
- }
-
- push(alert: AlertInfo): void {
- const newAlert: AlertInfoEx = { ...alert, id: this.currentId++ };
- if (this.consumers.length === 0) {
- this.savedAlerts.push(newAlert);
- } else {
- this.produce(newAlert);
- }
- }
-}
-
-export const alertService = new AlertService();
-
-export function pushAlert(alert: AlertInfo): void {
- alertService.push(alert);
-}
-
-export const kAlertHostId = 'alert-host';
-
-export function getAlertHost(): HTMLElement | null {
- return document.getElementById(kAlertHostId);
-}
+import React from "react"; +import pull from "lodash/pull"; + +export interface AlertInfo { + type?: "primary" | "secondary" | "success" | "danger" | "warning" | "info"; + message: string | React.FC<unknown> | { type: "i18n"; key: string }; + dismissTime?: number | "never"; +} + +export interface AlertInfoEx extends AlertInfo { + id: number; +} + +export type AlertConsumer = (alerts: AlertInfoEx) => void; + +export class AlertService { + private consumers: AlertConsumer[] = []; + private savedAlerts: AlertInfoEx[] = []; + private currentId = 1; + + private produce(alert: AlertInfoEx): void { + for (const consumer of this.consumers) { + consumer(alert); + } + } + + registerConsumer(consumer: AlertConsumer): void { + this.consumers.push(consumer); + if (this.savedAlerts.length !== 0) { + for (const alert of this.savedAlerts) { + this.produce(alert); + } + this.savedAlerts = []; + } + } + + unregisterConsumer(consumer: AlertConsumer): void { + pull(this.consumers, consumer); + } + + push(alert: AlertInfo): void { + const newAlert: AlertInfoEx = { ...alert, id: this.currentId++ }; + if (this.consumers.length === 0) { + this.savedAlerts.push(newAlert); + } else { + this.produce(newAlert); + } + } +} + +export const alertService = new AlertService(); + +export function pushAlert(alert: AlertInfo): void { + alertService.push(alert); +} + +export const kAlertHostId = "alert-host"; + +export function getAlertHost(): HTMLElement | null { + return document.getElementById(kAlertHostId); +} diff --git a/Timeline/ClientApp/src/app/common/alert.sass b/Timeline/ClientApp/src/app/common/alert.sass index c3560b87..5b6e65c2 100644 --- a/Timeline/ClientApp/src/app/common/alert.sass +++ b/Timeline/ClientApp/src/app/common/alert.sass @@ -1,15 +1,15 @@ -.alert-container
- position: fixed
- z-index: $zindex-popover
-
-@include media-breakpoint-up(sm)
- .alert-container
- bottom: 0
- right: 0
-
-@include media-breakpoint-down(sm)
- .alert-container
- bottom: 0
- right: 0
- left: 0
- text-align: center
+.alert-container + position: fixed + z-index: $zindex-popover + +@include media-breakpoint-up(sm) + .alert-container + bottom: 0 + right: 0 + +@include media-breakpoint-down(sm) + .alert-container + bottom: 0 + right: 0 + left: 0 + text-align: center diff --git a/Timeline/ClientApp/src/app/common/common.sass b/Timeline/ClientApp/src/app/common/common.sass index 78e6fd14..15d34d7c 100644 --- a/Timeline/ClientApp/src/app/common/common.sass +++ b/Timeline/ClientApp/src/app/common/common.sass @@ -1,33 +1,33 @@ -.image-cropper-container
- position: relative
- box-sizing: border-box
- user-select: none
-
-.image-cropper-container img
- position: absolute
- left: 0
- top: 0
- width: 100%
- height: 100%
-
-.image-cropper-mask-container
- position: absolute
- left: 0
- top: 0
- right: 0
- bottom: 0
- overflow: hidden
-
-.image-cropper-mask
- position: absolute
- box-shadow: 0 0 0 10000px rgba(255, 255, 255, 80%)
- touch-action: none
-
-.image-cropper-handler
- position: absolute
- width: 26px
- height: 26px
- border: black solid 2px
- border-radius: 50%
- background: white
- touch-action: none
+.image-cropper-container + position: relative + box-sizing: border-box + user-select: none + +.image-cropper-container img + position: absolute + left: 0 + top: 0 + width: 100% + height: 100% + +.image-cropper-mask-container + position: absolute + left: 0 + top: 0 + right: 0 + bottom: 0 + overflow: hidden + +.image-cropper-mask + position: absolute + box-shadow: 0 0 0 10000px rgba(255, 255, 255, 80%) + touch-action: none + +.image-cropper-handler + position: absolute + width: 26px + height: 26px + border: black solid 2px + border-radius: 50% + background: white + touch-action: none diff --git a/Timeline/ClientApp/src/app/data/DataHub.ts b/Timeline/ClientApp/src/app/data/DataHub.ts index bfb96d1a..e6be740d 100644 --- a/Timeline/ClientApp/src/app/data/DataHub.ts +++ b/Timeline/ClientApp/src/app/data/DataHub.ts @@ -1,198 +1,198 @@ -import { pull } from 'lodash';
-import { Observable, BehaviorSubject, combineLatest } from 'rxjs';
-import { map } from 'rxjs/operators';
-
-export type Subscriber<TData> = (data: TData) => void;
-
-export type WithSyncStatus<T> = T & { syncing: boolean };
-
-export class DataLine<TData> {
- private _current: TData | undefined = undefined;
-
- private _syncingSubject = new BehaviorSubject<boolean>(false);
-
- private _observers: Subscriber<TData>[] = [];
-
- constructor(
- private config?: { destroyable?: (value: TData | undefined) => boolean }
- ) {}
-
- private subscribe(subscriber: Subscriber<TData>): void {
- this._observers.push(subscriber);
- if (this._current !== undefined) {
- subscriber(this._current);
- }
- }
-
- private unsubscribe(subscriber: Subscriber<TData>): void {
- if (!this._observers.includes(subscriber)) return;
- pull(this._observers, subscriber);
- }
-
- getObservable(): Observable<TData> {
- return new Observable<TData>((observer) => {
- const f = (data: TData): void => {
- observer.next(data);
- };
- this.subscribe(f);
-
- return () => {
- this.unsubscribe(f);
- };
- });
- }
-
- getSyncStatusObservable(): Observable<boolean> {
- return this._syncingSubject.asObservable();
- }
-
- getDataWithSyncStatusObservable(): Observable<WithSyncStatus<TData>> {
- return combineLatest([
- this.getObservable(),
- this.getSyncStatusObservable(),
- ]).pipe(
- map(([data, syncing]) => ({
- ...data,
- syncing,
- }))
- );
- }
-
- get value(): TData | undefined {
- return this._current;
- }
-
- next(value: TData): void {
- this._current = value;
- this._observers.forEach((observer) => observer(value));
- }
-
- get isSyncing(): boolean {
- return this._syncingSubject.value;
- }
-
- beginSync(): void {
- if (!this._syncingSubject.value) {
- this._syncingSubject.next(true);
- }
- }
-
- endSync(): void {
- if (this._syncingSubject.value) {
- this._syncingSubject.next(false);
- }
- }
-
- get destroyable(): boolean {
- const customDestroyable = this.config?.destroyable;
-
- return (
- this._observers.length === 0 &&
- !this._syncingSubject.value &&
- (customDestroyable != null ? customDestroyable(this._current) : true)
- );
- }
-
- endSyncAndNext(value: TData): void {
- this.endSync();
- this.next(value);
- }
-}
-
-export class DataHub<TKey, TData> {
- private keyToString: (key: TKey) => string;
- private setup?: (key: TKey, line: DataLine<TData>) => (() => void) | void;
- private destroyable?: (key: TKey, value: TData | undefined) => boolean;
-
- private readonly subscriptionLineMap = new Map<string, DataLine<TData>>();
-
- private cleanTimerId = 0;
-
- // setup is called after creating line and if it returns a function as destroyer, then when the line is destroyed the destroyer will be called.
- constructor(config?: {
- keyToString?: (key: TKey) => string;
- setup?: (key: TKey, line: DataLine<TData>) => void;
- destroyable?: (key: TKey, value: TData | undefined) => boolean;
- }) {
- this.keyToString =
- config?.keyToString ??
- ((value): string => {
- if (typeof value === 'string') return value;
- else
- throw new Error(
- 'Default keyToString function only pass string value.'
- );
- });
-
- this.setup = config?.setup;
- this.destroyable = config?.destroyable;
- }
-
- private cleanLines(): void {
- const toDelete: string[] = [];
- for (const [key, line] of this.subscriptionLineMap.entries()) {
- if (line.destroyable) {
- toDelete.push(key);
- }
- }
-
- if (toDelete.length === 0) return;
-
- for (const key of toDelete) {
- this.subscriptionLineMap.delete(key);
- }
-
- if (this.subscriptionLineMap.size === 0) {
- window.clearInterval(this.cleanTimerId);
- this.cleanTimerId = 0;
- }
- }
-
- private createLine(key: TKey, useSetup = true): DataLine<TData> {
- const keyString = this.keyToString(key);
- const { setup, destroyable } = this;
- const newLine = new DataLine<TData>({
- destroyable:
- destroyable != null ? (value) => destroyable(key, value) : undefined,
- });
- this.subscriptionLineMap.set(keyString, newLine);
- if (useSetup) {
- setup?.(key, newLine);
- }
- if (this.subscriptionLineMap.size === 1) {
- this.cleanTimerId = window.setInterval(this.cleanLines.bind(this), 20000);
- }
- return newLine;
- }
-
- getObservable(key: TKey): Observable<TData> {
- return this.getLineOrCreateWithSetup(key).getObservable();
- }
-
- getSyncStatusObservable(key: TKey): Observable<boolean> {
- return this.getLineOrCreateWithSetup(key).getSyncStatusObservable();
- }
-
- getDataWithSyncStatusObservable(
- key: TKey
- ): Observable<WithSyncStatus<TData>> {
- return this.getLineOrCreateWithSetup(key).getDataWithSyncStatusObservable();
- }
-
- getLine(key: TKey): DataLine<TData> | null {
- const keyString = this.keyToString(key);
- return this.subscriptionLineMap.get(keyString) ?? null;
- }
-
- getLineOrCreateWithSetup(key: TKey): DataLine<TData> {
- const keyString = this.keyToString(key);
- return this.subscriptionLineMap.get(keyString) ?? this.createLine(key);
- }
-
- getLineOrCreateWithoutSetup(key: TKey): DataLine<TData> {
- const keyString = this.keyToString(key);
- return (
- this.subscriptionLineMap.get(keyString) ?? this.createLine(key, false)
- );
- }
-}
+import { pull } from "lodash"; +import { Observable, BehaviorSubject, combineLatest } from "rxjs"; +import { map } from "rxjs/operators"; + +export type Subscriber<TData> = (data: TData) => void; + +export type WithSyncStatus<T> = T & { syncing: boolean }; + +export class DataLine<TData> { + private _current: TData | undefined = undefined; + + private _syncingSubject = new BehaviorSubject<boolean>(false); + + private _observers: Subscriber<TData>[] = []; + + constructor( + private config?: { destroyable?: (value: TData | undefined) => boolean } + ) {} + + private subscribe(subscriber: Subscriber<TData>): void { + this._observers.push(subscriber); + if (this._current !== undefined) { + subscriber(this._current); + } + } + + private unsubscribe(subscriber: Subscriber<TData>): void { + if (!this._observers.includes(subscriber)) return; + pull(this._observers, subscriber); + } + + getObservable(): Observable<TData> { + return new Observable<TData>((observer) => { + const f = (data: TData): void => { + observer.next(data); + }; + this.subscribe(f); + + return () => { + this.unsubscribe(f); + }; + }); + } + + getSyncStatusObservable(): Observable<boolean> { + return this._syncingSubject.asObservable(); + } + + getDataWithSyncStatusObservable(): Observable<WithSyncStatus<TData>> { + return combineLatest([ + this.getObservable(), + this.getSyncStatusObservable(), + ]).pipe( + map(([data, syncing]) => ({ + ...data, + syncing, + })) + ); + } + + get value(): TData | undefined { + return this._current; + } + + next(value: TData): void { + this._current = value; + this._observers.forEach((observer) => observer(value)); + } + + get isSyncing(): boolean { + return this._syncingSubject.value; + } + + beginSync(): void { + if (!this._syncingSubject.value) { + this._syncingSubject.next(true); + } + } + + endSync(): void { + if (this._syncingSubject.value) { + this._syncingSubject.next(false); + } + } + + get destroyable(): boolean { + const customDestroyable = this.config?.destroyable; + + return ( + this._observers.length === 0 && + !this._syncingSubject.value && + (customDestroyable != null ? customDestroyable(this._current) : true) + ); + } + + endSyncAndNext(value: TData): void { + this.endSync(); + this.next(value); + } +} + +export class DataHub<TKey, TData> { + private keyToString: (key: TKey) => string; + private setup?: (key: TKey, line: DataLine<TData>) => (() => void) | void; + private destroyable?: (key: TKey, value: TData | undefined) => boolean; + + private readonly subscriptionLineMap = new Map<string, DataLine<TData>>(); + + private cleanTimerId = 0; + + // setup is called after creating line and if it returns a function as destroyer, then when the line is destroyed the destroyer will be called. + constructor(config?: { + keyToString?: (key: TKey) => string; + setup?: (key: TKey, line: DataLine<TData>) => void; + destroyable?: (key: TKey, value: TData | undefined) => boolean; + }) { + this.keyToString = + config?.keyToString ?? + ((value): string => { + if (typeof value === "string") return value; + else + throw new Error( + "Default keyToString function only pass string value." + ); + }); + + this.setup = config?.setup; + this.destroyable = config?.destroyable; + } + + private cleanLines(): void { + const toDelete: string[] = []; + for (const [key, line] of this.subscriptionLineMap.entries()) { + if (line.destroyable) { + toDelete.push(key); + } + } + + if (toDelete.length === 0) return; + + for (const key of toDelete) { + this.subscriptionLineMap.delete(key); + } + + if (this.subscriptionLineMap.size === 0) { + window.clearInterval(this.cleanTimerId); + this.cleanTimerId = 0; + } + } + + private createLine(key: TKey, useSetup = true): DataLine<TData> { + const keyString = this.keyToString(key); + const { setup, destroyable } = this; + const newLine = new DataLine<TData>({ + destroyable: + destroyable != null ? (value) => destroyable(key, value) : undefined, + }); + this.subscriptionLineMap.set(keyString, newLine); + if (useSetup) { + setup?.(key, newLine); + } + if (this.subscriptionLineMap.size === 1) { + this.cleanTimerId = window.setInterval(this.cleanLines.bind(this), 20000); + } + return newLine; + } + + getObservable(key: TKey): Observable<TData> { + return this.getLineOrCreateWithSetup(key).getObservable(); + } + + getSyncStatusObservable(key: TKey): Observable<boolean> { + return this.getLineOrCreateWithSetup(key).getSyncStatusObservable(); + } + + getDataWithSyncStatusObservable( + key: TKey + ): Observable<WithSyncStatus<TData>> { + return this.getLineOrCreateWithSetup(key).getDataWithSyncStatusObservable(); + } + + getLine(key: TKey): DataLine<TData> | null { + const keyString = this.keyToString(key); + return this.subscriptionLineMap.get(keyString) ?? null; + } + + getLineOrCreateWithSetup(key: TKey): DataLine<TData> { + const keyString = this.keyToString(key); + return this.subscriptionLineMap.get(keyString) ?? this.createLine(key); + } + + getLineOrCreateWithoutSetup(key: TKey): DataLine<TData> { + const keyString = this.keyToString(key); + return ( + this.subscriptionLineMap.get(keyString) ?? this.createLine(key, false) + ); + } +} diff --git a/Timeline/ClientApp/src/app/data/common.ts b/Timeline/ClientApp/src/app/data/common.ts index 87984e21..8d52abe5 100644 --- a/Timeline/ClientApp/src/app/data/common.ts +++ b/Timeline/ClientApp/src/app/data/common.ts @@ -1,23 +1,23 @@ -import localforage from 'localforage';
-
-import { HttpNetworkError } from '../http/common';
-
-export const dataStorage = localforage.createInstance({
- name: 'data',
- description: 'Database for offline data.',
- driver: localforage.INDEXEDDB,
-});
-
-export class ForbiddenError extends Error {
- constructor(message?: string) {
- super(message);
- }
-}
-
-export function throwIfNotNetworkError(e: unknown): void {
- if (!(e instanceof HttpNetworkError)) {
- throw e;
- }
-}
-
-export type BlobOrStatus = Blob | 'loading' | 'error';
+import localforage from "localforage"; + +import { HttpNetworkError } from "../http/common"; + +export const dataStorage = localforage.createInstance({ + name: "data", + description: "Database for offline data.", + driver: localforage.INDEXEDDB, +}); + +export class ForbiddenError extends Error { + constructor(message?: string) { + super(message); + } +} + +export function throwIfNotNetworkError(e: unknown): void { + if (!(e instanceof HttpNetworkError)) { + throw e; + } +} + +export type BlobOrStatus = Blob | "loading" | "error"; diff --git a/Timeline/ClientApp/src/app/data/timeline.ts b/Timeline/ClientApp/src/app/data/timeline.ts index 216d903c..ed6cffd6 100644 --- a/Timeline/ClientApp/src/app/data/timeline.ts +++ b/Timeline/ClientApp/src/app/data/timeline.ts @@ -1,697 +1,697 @@ -import React from 'react';
-import XRegExp from 'xregexp';
-import { Observable, from, combineLatest, of } from 'rxjs';
-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,
- HttpTimelinePatchRequest,
- HttpTimelinePostPostRequest,
- HttpTimelinePostPostRequestContent,
- HttpTimelinePostPostRequestTextContent,
- HttpTimelinePostPostRequestImageContent,
- HttpTimelinePostInfo,
- HttpTimelinePostTextContent,
- getHttpTimelineClient,
- HttpTimelineNotExistError,
- HttpTimelineNameConflictError,
-} from '../http/timeline';
-import { BlobWithEtag, NotModified, HttpForbiddenError } from '../http/common';
-import { HttpUser } from '../http/user';
-
-export type TimelineInfo = HttpTimelineInfo;
-export type TimelineChangePropertyRequest = HttpTimelinePatchRequest;
-export type TimelineCreatePostRequest = HttpTimelinePostPostRequest;
-export type TimelineCreatePostContent = HttpTimelinePostPostRequestContent;
-export type TimelineCreatePostTextContent = HttpTimelinePostPostRequestTextContent;
-export type TimelineCreatePostImageContent = HttpTimelinePostPostRequestImageContent;
-
-export type TimelinePostTextContent = HttpTimelinePostTextContent;
-
-export interface TimelinePostImageContent {
- type: 'image';
- data: BlobOrStatus;
-}
-
-export type TimelinePostContent =
- | TimelinePostTextContent
- | TimelinePostImageContent;
-
-export interface TimelinePostInfo {
- id: number;
- content: TimelinePostContent;
- time: Date;
- lastUpdated: Date;
- author: HttpUser;
-}
-
-export const timelineVisibilityTooltipTranslationMap: Record<
- TimelineVisibility,
- string
-> = {
- Public: 'timeline.visibilityTooltip.public',
- Register: 'timeline.visibilityTooltip.register',
- Private: 'timeline.visibilityTooltip.private',
-};
-
-export class TimelineNotExistError extends Error {}
-export class TimelineNameConflictError extends Error {}
-
-export type TimelineWithSyncStatus = WithSyncStatus<
- | {
- type: 'cache';
- timeline: TimelineInfo;
- }
- | {
- type: 'offline' | 'synced';
- timeline: TimelineInfo | null;
- }
->;
-
-export type TimelinePostsWithSyncState = WithSyncStatus<{
- type:
- | 'cache'
- | 'offline' // Sync failed and use cache.
- | 'synced' // Sync succeeded.
- | 'forbid' // The list is forbidden to see.
- | 'notexist'; // The timeline does not exist.
- posts: TimelinePostInfo[];
-}>;
-
-type TimelineData = Omit<HttpTimelineInfo, 'owner' | 'members'> & {
- owner: string;
- members: string[];
-};
-
-type TimelinePostData = Omit<HttpTimelinePostInfo, 'author'> & {
- author: string;
-};
-
-export class TimelineService {
- private getCachedTimeline(
- timelineName: string
- ): Promise<TimelineData | null> {
- return dataStorage.getItem<TimelineData | null>(`timeline.${timelineName}`);
- }
-
- private saveTimeline(
- timelineName: string,
- data: TimelineData
- ): Promise<void> {
- return dataStorage
- .setItem<TimelineData>(`timeline.${timelineName}`, data)
- .then();
- }
-
- private convertHttpTimelineToData(timeline: HttpTimelineInfo): TimelineData {
- return {
- ...timeline,
- owner: timeline.owner.username,
- members: timeline.members.map((m) => m.username),
- };
- }
-
- private async syncTimeline(timelineName: string): Promise<void> {
- const line = this._timelineHub.getLineOrCreateWithoutSetup(timelineName);
- if (line.isSyncing) return;
-
- if (line.value == undefined) {
- const cache = await this.getCachedTimeline(timelineName);
- if (cache != null) {
- line.next({ type: 'cache', timeline: cache });
- }
- }
-
- try {
- const httpTimeline = await getHttpTimelineClient().getTimeline(
- timelineName
- );
-
- [httpTimeline.owner, ...httpTimeline.members].forEach(
- (user) => void userInfoService.saveUser(user)
- );
-
- const timeline = this.convertHttpTimelineToData(httpTimeline);
- await this.saveTimeline(timelineName, timeline);
- line.endSyncAndNext({ type: 'synced', timeline });
- } catch (e) {
- if (e instanceof HttpTimelineNotExistError) {
- line.endSyncAndNext({ type: 'synced', timeline: null });
- } else {
- const cache = await this.getCachedTimeline(timelineName);
- if (cache == null) {
- line.endSyncAndNext({ type: 'offline', timeline: null });
- } else {
- line.endSyncAndNext({ type: 'offline', timeline: cache });
- }
- throwIfNotNetworkError(e);
- }
- }
- }
-
- private _timelineHub = new DataHub<
- string,
- | {
- type: 'cache';
- timeline: TimelineData;
- }
- | {
- type: 'offline' | 'synced';
- timeline: TimelineData | null;
- }
- >({
- setup: (key) => {
- void this.syncTimeline(key);
- },
- });
-
- getTimeline$(timelineName: string): Observable<TimelineWithSyncStatus> {
- return this._timelineHub.getDataWithSyncStatusObservable(timelineName).pipe(
- switchMap((state) => {
- const { timeline } = state;
- if (timeline != null) {
- return combineLatest(
- [timeline.owner, ...timeline.members].map((u) =>
- userInfoService.getUser$(u)
- )
- ).pipe(
- map((users) => {
- return {
- ...state,
- timeline: {
- ...timeline,
- owner: users[0],
- members: users.slice(1),
- },
- };
- })
- );
- } else {
- return of(state as TimelineWithSyncStatus);
- }
- })
- );
- }
-
- createTimeline(timelineName: string): Observable<TimelineInfo> {
- const user = checkLogin();
- return from(
- getHttpTimelineClient().postTimeline(
- {
- name: timelineName,
- },
- user.token
- )
- ).pipe(
- convertError(HttpTimelineNameConflictError, TimelineNameConflictError)
- );
- }
-
- changeTimelineProperty(
- timelineName: string,
- req: TimelineChangePropertyRequest
- ): Observable<TimelineInfo> {
- const user = checkLogin();
- return from(
- getHttpTimelineClient()
- .patchTimeline(timelineName, req, user.token)
- .then((timeline) => {
- void this.syncTimeline(timelineName);
- return timeline;
- })
- );
- }
-
- deleteTimeline(timelineName: string): Observable<unknown> {
- const user = checkLogin();
- return from(
- getHttpTimelineClient().deleteTimeline(timelineName, user.token)
- );
- }
-
- addMember(timelineName: string, username: string): Observable<unknown> {
- const user = checkLogin();
- return from(
- getHttpTimelineClient()
- .memberPut(timelineName, username, user.token)
- .then(() => {
- void this.syncTimeline(timelineName);
- })
- );
- }
-
- removeMember(timelineName: string, username: string): Observable<unknown> {
- const user = checkLogin();
- return from(
- getHttpTimelineClient()
- .memberDelete(timelineName, username, user.token)
- .then(() => {
- void this.syncTimeline(timelineName);
- })
- );
- }
-
- private convertHttpPostToData(post: HttpTimelinePostInfo): TimelinePostData {
- return {
- ...post,
- author: post.author.username,
- };
- }
-
- private convertHttpPostToDataList(
- posts: HttpTimelinePostInfo[]
- ): TimelinePostData[] {
- return posts.map((post) => this.convertHttpPostToData(post));
- }
-
- private getCachedPosts(
- timelineName: string
- ): Promise<TimelinePostData[] | null> {
- return dataStorage.getItem<TimelinePostData[] | null>(
- `timeline.${timelineName}.posts`
- );
- }
-
- private savePosts(
- timelineName: string,
- data: TimelinePostData[]
- ): Promise<void> {
- return dataStorage
- .setItem<TimelinePostData[]>(`timeline.${timelineName}.posts`, data)
- .then();
- }
-
- private async syncPosts(timelineName: string): Promise<void> {
- const line = this._postsHub.getLineOrCreateWithoutSetup(timelineName);
- if (line.isSyncing) return;
- line.beginSync();
-
- if (line.value == null) {
- const cache = await this.getCachedPosts(timelineName);
- if (cache != null) {
- line.next({ type: 'cache', posts: cache });
- }
- }
-
- const now = new Date();
-
- const lastUpdatedTime = await dataStorage.getItem<Date | null>(
- `timeline.${timelineName}.lastUpdated`
- );
-
- try {
- if (lastUpdatedTime == null) {
- const httpPosts = await getHttpTimelineClient().listPost(
- timelineName,
- userService.currentUser?.token
- );
-
- uniqBy(
- httpPosts.map((post) => post.author),
- 'username'
- ).forEach((user) => void userInfoService.saveUser(user));
-
- const posts = this.convertHttpPostToDataList(httpPosts);
- await this.savePosts(timelineName, posts);
- await dataStorage.setItem<Date>(
- `timeline.${timelineName}.lastUpdated`,
- now
- );
-
- line.endSyncAndNext({ type: 'synced', posts });
- } else {
- const httpPosts = await getHttpTimelineClient().listPost(
- timelineName,
- userService.currentUser?.token,
- {
- modifiedSince: lastUpdatedTime,
- includeDeleted: true,
- }
- );
-
- const deletedIds = httpPosts.filter((p) => p.deleted).map((p) => p.id);
- const changed = httpPosts.filter(
- (p): p is HttpTimelinePostInfo => !p.deleted
- );
-
- uniqBy(
- httpPosts
- .map((post) => post.author)
- .filter((u): u is HttpUser => u != null),
- 'username'
- ).forEach((user) => void userInfoService.saveUser(user));
-
- const cache = (await this.getCachedPosts(timelineName)) ?? [];
-
- const posts = cache.filter((p) => !deletedIds.includes(p.id));
-
- for (const changedPost of changed) {
- const savedChangedPostIndex = posts.findIndex(
- (p) => p.id === changedPost.id
- );
- if (savedChangedPostIndex === -1) {
- posts.push(this.convertHttpPostToData(changedPost));
- } else {
- posts[savedChangedPostIndex] = this.convertHttpPostToData(
- changedPost
- );
- }
- }
-
- await this.savePosts(timelineName, posts);
- await dataStorage.setItem<Date>(
- `timeline.${timelineName}.lastUpdated`,
- now
- );
- line.endSyncAndNext({ type: 'synced', posts });
- }
- } catch (e) {
- if (e instanceof HttpTimelineNotExistError) {
- line.endSyncAndNext({ type: 'notexist', posts: [] });
- } else if (e instanceof HttpForbiddenError) {
- line.endSyncAndNext({ type: 'forbid', posts: [] });
- } else {
- const cache = await this.getCachedPosts(timelineName);
- if (cache == null) {
- line.endSyncAndNext({ type: 'offline', posts: [] });
- } else {
- line.endSyncAndNext({ type: 'offline', posts: cache });
- }
- throwIfNotNetworkError(e);
- }
- }
- }
-
- private _postsHub = new DataHub<
- string,
- {
- type: 'cache' | 'offline' | 'synced' | 'forbid' | 'notexist';
- posts: TimelinePostData[];
- }
- >({
- setup: (key) => {
- void this.syncPosts(key);
- },
- });
-
- getPosts$(timelineName: string): Observable<TimelinePostsWithSyncState> {
- return this._postsHub.getDataWithSyncStatusObservable(timelineName).pipe(
- switchMap((state) => {
- if (state.posts.length === 0) {
- return of({
- ...state,
- posts: [],
- });
- }
-
- return combineLatest([
- combineLatest(
- state.posts.map((post) => userInfoService.getUser$(post.author))
- ),
- combineLatest(
- state.posts.map((post) => {
- if (post.content.type === 'image') {
- return this.getPostData$(timelineName, post.id);
- } else {
- return of(null);
- }
- })
- ),
- ]).pipe(
- map(([authors, datas]) => {
- return {
- ...state,
- posts: state.posts.map((post, i) => {
- const { content } = post;
-
- return {
- ...post,
- author: authors[i],
- content: (() => {
- if (content.type === 'text') return content;
- else
- return {
- type: 'image',
- data: datas[i],
- } as TimelinePostImageContent;
- })(),
- };
- }),
- };
- })
- );
- })
- );
- }
-
- private getCachedPostData(key: {
- timelineName: string;
- postId: number;
- }): Promise<BlobWithEtag | null> {
- return dataStorage.getItem<BlobWithEtag | null>(
- `timeline.${key.timelineName}.post.${key.postId}.data`
- );
- }
-
- private savePostData(
- key: {
- timelineName: string;
- postId: number;
- },
- data: BlobWithEtag
- ): Promise<void> {
- return dataStorage
- .setItem<BlobWithEtag>(
- `timeline.${key.timelineName}.post.${key.postId}.data`,
- data
- )
- .then();
- }
-
- private async syncPostData(key: {
- timelineName: string;
- postId: number;
- }): Promise<void> {
- const line = this._postDataHub.getLineOrCreateWithoutSetup(key);
- if (line.isSyncing) return;
- line.beginSync();
-
- const cache = await this.getCachedPostData(key);
- if (line.value == null) {
- if (cache != null) {
- line.next({ type: 'cache', data: cache.data });
- }
- }
-
- if (cache == null) {
- try {
- const res = await getHttpTimelineClient().getPostData(
- key.timelineName,
- key.postId
- );
- await this.savePostData(key, res);
- line.endSyncAndNext({ data: res.data, type: 'synced' });
- } catch (e) {
- line.endSyncAndNext({ type: 'offline' });
- throwIfNotNetworkError(e);
- }
- } else {
- try {
- const res = await getHttpTimelineClient().getPostData(
- key.timelineName,
- key.postId,
- cache.etag
- );
- if (res instanceof NotModified) {
- line.endSyncAndNext({ data: cache.data, type: 'synced' });
- } else {
- await this.savePostData(key, res);
- line.endSyncAndNext({ data: res.data, type: 'synced' });
- }
- } catch (e) {
- line.endSyncAndNext({ data: cache.data, type: 'offline' });
- throwIfNotNetworkError(e);
- }
- }
- }
-
- private _postDataHub = new DataHub<
- { timelineName: string; postId: number },
- | { data: Blob; type: 'cache' | 'synced' | 'offline' }
- | { data?: undefined; type: 'notexist' | 'offline' }
- >({
- keyToString: (key) => `${key.timelineName}.${key.postId}`,
- setup: (key) => {
- void this.syncPostData(key);
- },
- });
-
- getPostData$(timelineName: string, postId: number): Observable<BlobOrStatus> {
- return this._postDataHub.getObservable({ timelineName, postId }).pipe(
- map((state): BlobOrStatus => state.data ?? 'error'),
- startWith('loading')
- );
- }
-
- createPost(
- timelineName: string,
- request: TimelineCreatePostRequest
- ): Observable<unknown> {
- const user = checkLogin();
- return from(
- getHttpTimelineClient()
- .postPost(timelineName, request, user.token)
- .then(() => {
- void this.syncPosts(timelineName);
- })
- );
- }
-
- deletePost(timelineName: string, postId: number): Observable<unknown> {
- const user = checkLogin();
- return from(
- getHttpTimelineClient()
- .deletePost(timelineName, postId, user.token)
- .then(() => {
- void this.syncPosts(timelineName);
- })
- );
- }
-
- isMemberOf(username: string, timeline: TimelineInfo): boolean {
- return timeline.members.findIndex((m) => m.username == username) >= 0;
- }
-
- hasReadPermission(
- user: UserAuthInfo | null | undefined,
- timeline: TimelineInfo
- ): boolean {
- if (user != null && user.administrator) return true;
-
- const { visibility } = timeline;
- if (visibility === 'Public') {
- return true;
- } else if (visibility === 'Register') {
- if (user != null) return true;
- } else if (visibility === 'Private') {
- if (
- user != null &&
- (user.username === timeline.owner.username ||
- this.isMemberOf(user.username, timeline))
- ) {
- return true;
- }
- }
- return false;
- }
-
- hasPostPermission(
- user: UserAuthInfo | null | undefined,
- timeline: TimelineInfo
- ): boolean {
- if (user != null && user.administrator) return true;
-
- return (
- user != null &&
- (timeline.owner.username === user.username ||
- this.isMemberOf(user.username, timeline))
- );
- }
-
- hasManagePermission(
- user: UserAuthInfo | null | undefined,
- timeline: TimelineInfo
- ): boolean {
- if (user != null && user.administrator) return true;
-
- return user != null && user.username == timeline.owner.username;
- }
-
- hasModifyPostPermission(
- user: UserAuthInfo | null | undefined,
- timeline: TimelineInfo,
- post: TimelinePostInfo
- ): boolean {
- if (user != null && user.administrator) return true;
-
- return (
- user != null &&
- (user.username === timeline.owner.username ||
- user.username === post.author.username)
- );
- }
-}
-
-export const timelineService = new TimelineService();
-
-const timelineNameReg = XRegExp('^[-_\\p{L}]*$', 'u');
-
-export function validateTimelineName(name: string): boolean {
- return timelineNameReg.test(name);
-}
-
-export function useTimelineInfo(
- timelineName: string
-): TimelineWithSyncStatus | undefined {
- const [state, setState] = React.useState<TimelineWithSyncStatus | undefined>(
- undefined
- );
- React.useEffect(() => {
- const subscription = timelineService
- .getTimeline$(timelineName)
- .subscribe((data) => {
- setState(data);
- });
- return () => {
- subscription.unsubscribe();
- };
- }, [timelineName]);
- return state;
-}
-
-export function usePostList(
- timelineName: string | null | undefined
-): TimelinePostsWithSyncState | undefined {
- const [state, setState] = React.useState<
- TimelinePostsWithSyncState | undefined
- >(undefined);
- React.useEffect(() => {
- if (timelineName == null) {
- setState(undefined);
- return;
- }
-
- const subscription = timelineService
- .getPosts$(timelineName)
- .subscribe((data) => {
- setState(data);
- });
- return () => {
- subscription.unsubscribe();
- };
- }, [timelineName]);
- return state;
-}
-
-export async function getAllCachedTimelineNames(): Promise<string[]> {
- const keys = await dataStorage.keys();
- return keys
- .filter(
- (key) =>
- key.startsWith('timeline.') && (key.match(/\./g) ?? []).length === 1
- )
- .map((key) => key.substr('timeline.'.length));
-}
+import React from "react"; +import XRegExp from "xregexp"; +import { Observable, from, combineLatest, of } from "rxjs"; +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, + HttpTimelinePatchRequest, + HttpTimelinePostPostRequest, + HttpTimelinePostPostRequestContent, + HttpTimelinePostPostRequestTextContent, + HttpTimelinePostPostRequestImageContent, + HttpTimelinePostInfo, + HttpTimelinePostTextContent, + getHttpTimelineClient, + HttpTimelineNotExistError, + HttpTimelineNameConflictError, +} from "../http/timeline"; +import { BlobWithEtag, NotModified, HttpForbiddenError } from "../http/common"; +import { HttpUser } from "../http/user"; + +export type TimelineInfo = HttpTimelineInfo; +export type TimelineChangePropertyRequest = HttpTimelinePatchRequest; +export type TimelineCreatePostRequest = HttpTimelinePostPostRequest; +export type TimelineCreatePostContent = HttpTimelinePostPostRequestContent; +export type TimelineCreatePostTextContent = HttpTimelinePostPostRequestTextContent; +export type TimelineCreatePostImageContent = HttpTimelinePostPostRequestImageContent; + +export type TimelinePostTextContent = HttpTimelinePostTextContent; + +export interface TimelinePostImageContent { + type: "image"; + data: BlobOrStatus; +} + +export type TimelinePostContent = + | TimelinePostTextContent + | TimelinePostImageContent; + +export interface TimelinePostInfo { + id: number; + content: TimelinePostContent; + time: Date; + lastUpdated: Date; + author: HttpUser; +} + +export const timelineVisibilityTooltipTranslationMap: Record< + TimelineVisibility, + string +> = { + Public: "timeline.visibilityTooltip.public", + Register: "timeline.visibilityTooltip.register", + Private: "timeline.visibilityTooltip.private", +}; + +export class TimelineNotExistError extends Error {} +export class TimelineNameConflictError extends Error {} + +export type TimelineWithSyncStatus = WithSyncStatus< + | { + type: "cache"; + timeline: TimelineInfo; + } + | { + type: "offline" | "synced"; + timeline: TimelineInfo | null; + } +>; + +export type TimelinePostsWithSyncState = WithSyncStatus<{ + type: + | "cache" + | "offline" // Sync failed and use cache. + | "synced" // Sync succeeded. + | "forbid" // The list is forbidden to see. + | "notexist"; // The timeline does not exist. + posts: TimelinePostInfo[]; +}>; + +type TimelineData = Omit<HttpTimelineInfo, "owner" | "members"> & { + owner: string; + members: string[]; +}; + +type TimelinePostData = Omit<HttpTimelinePostInfo, "author"> & { + author: string; +}; + +export class TimelineService { + private getCachedTimeline( + timelineName: string + ): Promise<TimelineData | null> { + return dataStorage.getItem<TimelineData | null>(`timeline.${timelineName}`); + } + + private saveTimeline( + timelineName: string, + data: TimelineData + ): Promise<void> { + return dataStorage + .setItem<TimelineData>(`timeline.${timelineName}`, data) + .then(); + } + + private convertHttpTimelineToData(timeline: HttpTimelineInfo): TimelineData { + return { + ...timeline, + owner: timeline.owner.username, + members: timeline.members.map((m) => m.username), + }; + } + + private async syncTimeline(timelineName: string): Promise<void> { + const line = this._timelineHub.getLineOrCreateWithoutSetup(timelineName); + if (line.isSyncing) return; + + if (line.value == undefined) { + const cache = await this.getCachedTimeline(timelineName); + if (cache != null) { + line.next({ type: "cache", timeline: cache }); + } + } + + try { + const httpTimeline = await getHttpTimelineClient().getTimeline( + timelineName + ); + + [httpTimeline.owner, ...httpTimeline.members].forEach( + (user) => void userInfoService.saveUser(user) + ); + + const timeline = this.convertHttpTimelineToData(httpTimeline); + await this.saveTimeline(timelineName, timeline); + line.endSyncAndNext({ type: "synced", timeline }); + } catch (e) { + if (e instanceof HttpTimelineNotExistError) { + line.endSyncAndNext({ type: "synced", timeline: null }); + } else { + const cache = await this.getCachedTimeline(timelineName); + if (cache == null) { + line.endSyncAndNext({ type: "offline", timeline: null }); + } else { + line.endSyncAndNext({ type: "offline", timeline: cache }); + } + throwIfNotNetworkError(e); + } + } + } + + private _timelineHub = new DataHub< + string, + | { + type: "cache"; + timeline: TimelineData; + } + | { + type: "offline" | "synced"; + timeline: TimelineData | null; + } + >({ + setup: (key) => { + void this.syncTimeline(key); + }, + }); + + getTimeline$(timelineName: string): Observable<TimelineWithSyncStatus> { + return this._timelineHub.getDataWithSyncStatusObservable(timelineName).pipe( + switchMap((state) => { + const { timeline } = state; + if (timeline != null) { + return combineLatest( + [timeline.owner, ...timeline.members].map((u) => + userInfoService.getUser$(u) + ) + ).pipe( + map((users) => { + return { + ...state, + timeline: { + ...timeline, + owner: users[0], + members: users.slice(1), + }, + }; + }) + ); + } else { + return of(state as TimelineWithSyncStatus); + } + }) + ); + } + + createTimeline(timelineName: string): Observable<TimelineInfo> { + const user = checkLogin(); + return from( + getHttpTimelineClient().postTimeline( + { + name: timelineName, + }, + user.token + ) + ).pipe( + convertError(HttpTimelineNameConflictError, TimelineNameConflictError) + ); + } + + changeTimelineProperty( + timelineName: string, + req: TimelineChangePropertyRequest + ): Observable<TimelineInfo> { + const user = checkLogin(); + return from( + getHttpTimelineClient() + .patchTimeline(timelineName, req, user.token) + .then((timeline) => { + void this.syncTimeline(timelineName); + return timeline; + }) + ); + } + + deleteTimeline(timelineName: string): Observable<unknown> { + const user = checkLogin(); + return from( + getHttpTimelineClient().deleteTimeline(timelineName, user.token) + ); + } + + addMember(timelineName: string, username: string): Observable<unknown> { + const user = checkLogin(); + return from( + getHttpTimelineClient() + .memberPut(timelineName, username, user.token) + .then(() => { + void this.syncTimeline(timelineName); + }) + ); + } + + removeMember(timelineName: string, username: string): Observable<unknown> { + const user = checkLogin(); + return from( + getHttpTimelineClient() + .memberDelete(timelineName, username, user.token) + .then(() => { + void this.syncTimeline(timelineName); + }) + ); + } + + private convertHttpPostToData(post: HttpTimelinePostInfo): TimelinePostData { + return { + ...post, + author: post.author.username, + }; + } + + private convertHttpPostToDataList( + posts: HttpTimelinePostInfo[] + ): TimelinePostData[] { + return posts.map((post) => this.convertHttpPostToData(post)); + } + + private getCachedPosts( + timelineName: string + ): Promise<TimelinePostData[] | null> { + return dataStorage.getItem<TimelinePostData[] | null>( + `timeline.${timelineName}.posts` + ); + } + + private savePosts( + timelineName: string, + data: TimelinePostData[] + ): Promise<void> { + return dataStorage + .setItem<TimelinePostData[]>(`timeline.${timelineName}.posts`, data) + .then(); + } + + private async syncPosts(timelineName: string): Promise<void> { + const line = this._postsHub.getLineOrCreateWithoutSetup(timelineName); + if (line.isSyncing) return; + line.beginSync(); + + if (line.value == null) { + const cache = await this.getCachedPosts(timelineName); + if (cache != null) { + line.next({ type: "cache", posts: cache }); + } + } + + const now = new Date(); + + const lastUpdatedTime = await dataStorage.getItem<Date | null>( + `timeline.${timelineName}.lastUpdated` + ); + + try { + if (lastUpdatedTime == null) { + const httpPosts = await getHttpTimelineClient().listPost( + timelineName, + userService.currentUser?.token + ); + + uniqBy( + httpPosts.map((post) => post.author), + "username" + ).forEach((user) => void userInfoService.saveUser(user)); + + const posts = this.convertHttpPostToDataList(httpPosts); + await this.savePosts(timelineName, posts); + await dataStorage.setItem<Date>( + `timeline.${timelineName}.lastUpdated`, + now + ); + + line.endSyncAndNext({ type: "synced", posts }); + } else { + const httpPosts = await getHttpTimelineClient().listPost( + timelineName, + userService.currentUser?.token, + { + modifiedSince: lastUpdatedTime, + includeDeleted: true, + } + ); + + const deletedIds = httpPosts.filter((p) => p.deleted).map((p) => p.id); + const changed = httpPosts.filter( + (p): p is HttpTimelinePostInfo => !p.deleted + ); + + uniqBy( + httpPosts + .map((post) => post.author) + .filter((u): u is HttpUser => u != null), + "username" + ).forEach((user) => void userInfoService.saveUser(user)); + + const cache = (await this.getCachedPosts(timelineName)) ?? []; + + const posts = cache.filter((p) => !deletedIds.includes(p.id)); + + for (const changedPost of changed) { + const savedChangedPostIndex = posts.findIndex( + (p) => p.id === changedPost.id + ); + if (savedChangedPostIndex === -1) { + posts.push(this.convertHttpPostToData(changedPost)); + } else { + posts[savedChangedPostIndex] = this.convertHttpPostToData( + changedPost + ); + } + } + + await this.savePosts(timelineName, posts); + await dataStorage.setItem<Date>( + `timeline.${timelineName}.lastUpdated`, + now + ); + line.endSyncAndNext({ type: "synced", posts }); + } + } catch (e) { + if (e instanceof HttpTimelineNotExistError) { + line.endSyncAndNext({ type: "notexist", posts: [] }); + } else if (e instanceof HttpForbiddenError) { + line.endSyncAndNext({ type: "forbid", posts: [] }); + } else { + const cache = await this.getCachedPosts(timelineName); + if (cache == null) { + line.endSyncAndNext({ type: "offline", posts: [] }); + } else { + line.endSyncAndNext({ type: "offline", posts: cache }); + } + throwIfNotNetworkError(e); + } + } + } + + private _postsHub = new DataHub< + string, + { + type: "cache" | "offline" | "synced" | "forbid" | "notexist"; + posts: TimelinePostData[]; + } + >({ + setup: (key) => { + void this.syncPosts(key); + }, + }); + + getPosts$(timelineName: string): Observable<TimelinePostsWithSyncState> { + return this._postsHub.getDataWithSyncStatusObservable(timelineName).pipe( + switchMap((state) => { + if (state.posts.length === 0) { + return of({ + ...state, + posts: [], + }); + } + + return combineLatest([ + combineLatest( + state.posts.map((post) => userInfoService.getUser$(post.author)) + ), + combineLatest( + state.posts.map((post) => { + if (post.content.type === "image") { + return this.getPostData$(timelineName, post.id); + } else { + return of(null); + } + }) + ), + ]).pipe( + map(([authors, datas]) => { + return { + ...state, + posts: state.posts.map((post, i) => { + const { content } = post; + + return { + ...post, + author: authors[i], + content: (() => { + if (content.type === "text") return content; + else + return { + type: "image", + data: datas[i], + } as TimelinePostImageContent; + })(), + }; + }), + }; + }) + ); + }) + ); + } + + private getCachedPostData(key: { + timelineName: string; + postId: number; + }): Promise<BlobWithEtag | null> { + return dataStorage.getItem<BlobWithEtag | null>( + `timeline.${key.timelineName}.post.${key.postId}.data` + ); + } + + private savePostData( + key: { + timelineName: string; + postId: number; + }, + data: BlobWithEtag + ): Promise<void> { + return dataStorage + .setItem<BlobWithEtag>( + `timeline.${key.timelineName}.post.${key.postId}.data`, + data + ) + .then(); + } + + private async syncPostData(key: { + timelineName: string; + postId: number; + }): Promise<void> { + const line = this._postDataHub.getLineOrCreateWithoutSetup(key); + if (line.isSyncing) return; + line.beginSync(); + + const cache = await this.getCachedPostData(key); + if (line.value == null) { + if (cache != null) { + line.next({ type: "cache", data: cache.data }); + } + } + + if (cache == null) { + try { + const res = await getHttpTimelineClient().getPostData( + key.timelineName, + key.postId + ); + await this.savePostData(key, res); + line.endSyncAndNext({ data: res.data, type: "synced" }); + } catch (e) { + line.endSyncAndNext({ type: "offline" }); + throwIfNotNetworkError(e); + } + } else { + try { + const res = await getHttpTimelineClient().getPostData( + key.timelineName, + key.postId, + cache.etag + ); + if (res instanceof NotModified) { + line.endSyncAndNext({ data: cache.data, type: "synced" }); + } else { + await this.savePostData(key, res); + line.endSyncAndNext({ data: res.data, type: "synced" }); + } + } catch (e) { + line.endSyncAndNext({ data: cache.data, type: "offline" }); + throwIfNotNetworkError(e); + } + } + } + + private _postDataHub = new DataHub< + { timelineName: string; postId: number }, + | { data: Blob; type: "cache" | "synced" | "offline" } + | { data?: undefined; type: "notexist" | "offline" } + >({ + keyToString: (key) => `${key.timelineName}.${key.postId}`, + setup: (key) => { + void this.syncPostData(key); + }, + }); + + getPostData$(timelineName: string, postId: number): Observable<BlobOrStatus> { + return this._postDataHub.getObservable({ timelineName, postId }).pipe( + map((state): BlobOrStatus => state.data ?? "error"), + startWith("loading") + ); + } + + createPost( + timelineName: string, + request: TimelineCreatePostRequest + ): Observable<unknown> { + const user = checkLogin(); + return from( + getHttpTimelineClient() + .postPost(timelineName, request, user.token) + .then(() => { + void this.syncPosts(timelineName); + }) + ); + } + + deletePost(timelineName: string, postId: number): Observable<unknown> { + const user = checkLogin(); + return from( + getHttpTimelineClient() + .deletePost(timelineName, postId, user.token) + .then(() => { + void this.syncPosts(timelineName); + }) + ); + } + + isMemberOf(username: string, timeline: TimelineInfo): boolean { + return timeline.members.findIndex((m) => m.username == username) >= 0; + } + + hasReadPermission( + user: UserAuthInfo | null | undefined, + timeline: TimelineInfo + ): boolean { + if (user != null && user.administrator) return true; + + const { visibility } = timeline; + if (visibility === "Public") { + return true; + } else if (visibility === "Register") { + if (user != null) return true; + } else if (visibility === "Private") { + if ( + user != null && + (user.username === timeline.owner.username || + this.isMemberOf(user.username, timeline)) + ) { + return true; + } + } + return false; + } + + hasPostPermission( + user: UserAuthInfo | null | undefined, + timeline: TimelineInfo + ): boolean { + if (user != null && user.administrator) return true; + + return ( + user != null && + (timeline.owner.username === user.username || + this.isMemberOf(user.username, timeline)) + ); + } + + hasManagePermission( + user: UserAuthInfo | null | undefined, + timeline: TimelineInfo + ): boolean { + if (user != null && user.administrator) return true; + + return user != null && user.username == timeline.owner.username; + } + + hasModifyPostPermission( + user: UserAuthInfo | null | undefined, + timeline: TimelineInfo, + post: TimelinePostInfo + ): boolean { + if (user != null && user.administrator) return true; + + return ( + user != null && + (user.username === timeline.owner.username || + user.username === post.author.username) + ); + } +} + +export const timelineService = new TimelineService(); + +const timelineNameReg = XRegExp("^[-_\\p{L}]*$", "u"); + +export function validateTimelineName(name: string): boolean { + return timelineNameReg.test(name); +} + +export function useTimelineInfo( + timelineName: string +): TimelineWithSyncStatus | undefined { + const [state, setState] = React.useState<TimelineWithSyncStatus | undefined>( + undefined + ); + React.useEffect(() => { + const subscription = timelineService + .getTimeline$(timelineName) + .subscribe((data) => { + setState(data); + }); + return () => { + subscription.unsubscribe(); + }; + }, [timelineName]); + return state; +} + +export function usePostList( + timelineName: string | null | undefined +): TimelinePostsWithSyncState | undefined { + const [state, setState] = React.useState< + TimelinePostsWithSyncState | undefined + >(undefined); + React.useEffect(() => { + if (timelineName == null) { + setState(undefined); + return; + } + + const subscription = timelineService + .getPosts$(timelineName) + .subscribe((data) => { + setState(data); + }); + return () => { + subscription.unsubscribe(); + }; + }, [timelineName]); + return state; +} + +export async function getAllCachedTimelineNames(): Promise<string[]> { + const keys = await dataStorage.keys(); + return keys + .filter( + (key) => + key.startsWith("timeline.") && (key.match(/\./g) ?? []).length === 1 + ) + .map((key) => key.substr("timeline.".length)); +} diff --git a/Timeline/ClientApp/src/app/data/user.ts b/Timeline/ClientApp/src/app/data/user.ts index 419cff18..8aee0c5f 100644 --- a/Timeline/ClientApp/src/app/data/user.ts +++ b/Timeline/ClientApp/src/app/data/user.ts @@ -1,389 +1,389 @@ -import React, { useState, useEffect } from 'react';
-import { BehaviorSubject, Observable, from } from 'rxjs';
-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,
- HttpCreateTokenBadCredentialError,
-} from '../http/token';
-import {
- getHttpUserClient,
- HttpUserNotExistError,
- HttpUser,
-} from '../http/user';
-
-export type User = HttpUser;
-
-export interface UserAuthInfo {
- username: string;
- administrator: boolean;
-}
-
-export interface UserWithToken extends User {
- token: string;
-}
-
-export interface LoginCredentials {
- username: string;
- password: string;
-}
-
-export class BadCredentialError {
- message = 'login.badCredential';
-}
-
-const USER_STORAGE_KEY = 'currentuser';
-
-export class UserService {
- private userSubject = new BehaviorSubject<UserWithToken | null | undefined>(
- undefined
- );
-
- get user$(): Observable<UserWithToken | null | undefined> {
- return this.userSubject;
- }
-
- get currentUser(): UserWithToken | null | undefined {
- return this.userSubject.value;
- }
-
- async checkLoginState(): Promise<UserWithToken | null> {
- if (this.currentUser !== undefined) {
- console.warn("Already checked user. Can't check twice.");
- }
-
- const savedUser = await dataStorage.getItem<UserWithToken | null>(
- USER_STORAGE_KEY
- );
-
- if (savedUser == null) {
- this.userSubject.next(null);
- return null;
- }
-
- this.userSubject.next(savedUser);
-
- const savedToken = savedUser.token;
- try {
- const res = await getHttpTokenClient().verify({ token: savedToken });
- const user: UserWithToken = { ...res.user, token: savedToken };
- await dataStorage.setItem<UserWithToken>(USER_STORAGE_KEY, user);
- this.userSubject.next(user);
- pushAlert({
- type: 'success',
- message: {
- type: 'i18n',
- key: 'user.welcomeBack',
- },
- });
- return user;
- } catch (error) {
- if (error instanceof HttpNetworkError) {
- pushAlert({
- type: 'danger',
- message: { type: 'i18n', key: 'user.verifyTokenFailedNetwork' },
- });
- return savedUser;
- } else {
- await dataStorage.removeItem(USER_STORAGE_KEY);
- this.userSubject.next(null);
- pushAlert({
- type: 'danger',
- message: { type: 'i18n', key: 'user.verifyTokenFailed' },
- });
- return null;
- }
- }
- }
-
- async login(
- credentials: LoginCredentials,
- rememberMe: boolean
- ): Promise<void> {
- if (this.currentUser) {
- throw new UiLogicError('Already login.');
- }
- try {
- const res = await getHttpTokenClient().create({
- ...credentials,
- expire: 30,
- });
- const user: UserWithToken = {
- ...res.user,
- token: res.token,
- };
- if (rememberMe) {
- await dataStorage.setItem<UserWithToken>(USER_STORAGE_KEY, user);
- }
- this.userSubject.next(user);
- } catch (e) {
- if (e instanceof HttpCreateTokenBadCredentialError) {
- throw new BadCredentialError();
- } else {
- throw e;
- }
- }
- }
-
- async logout(): Promise<void> {
- if (this.currentUser === undefined) {
- throw new UiLogicError('Please check user first.');
- }
- if (this.currentUser === null) {
- throw new UiLogicError('No login.');
- }
- await dataStorage.removeItem(USER_STORAGE_KEY);
- this.userSubject.next(null);
- }
-
- changePassword(
- oldPassword: string,
- newPassword: string
- ): Observable<unknown> {
- if (this.currentUser == undefined) {
- throw new UiLogicError("Not login or checked now, can't log out.");
- }
- const $ = from(
- getHttpUserClient().changePassword(
- {
- oldPassword,
- newPassword,
- },
- this.currentUser.token
- )
- );
- $.subscribe(() => {
- void this.logout();
- });
- return $;
- }
-}
-
-export const userService = new UserService();
-
-export function useRawUser(): UserWithToken | null | undefined {
- const [user, setUser] = useState<UserWithToken | null | undefined>(
- userService.currentUser
- );
- useEffect(() => {
- const subscription = userService.user$.subscribe((u) => setUser(u));
- return () => {
- subscription.unsubscribe();
- };
- });
- return user;
-}
-
-export function useUser(): UserWithToken | null {
- const [user, setUser] = useState<UserWithToken | null>(() => {
- const initUser = userService.currentUser;
- if (initUser === undefined) {
- throw new UiLogicError(
- "This is a logic error in user module. Current user can't be undefined in useUser."
- );
- }
- return initUser;
- });
- useEffect(() => {
- const sub = userService.user$.subscribe((u) => {
- if (u === undefined) {
- throw new UiLogicError(
- "This is a logic error in user module. User emitted can't be undefined later."
- );
- }
- setUser(u);
- });
- return () => {
- sub.unsubscribe();
- };
- });
- return user;
-}
-
-export function useUserLoggedIn(): UserWithToken {
- const user = useUser();
- if (user == null) {
- throw new UiLogicError('You assert user has logged in but actually not.');
- }
- return user;
-}
-
-export function checkLogin(): UserWithToken {
- const user = userService.currentUser;
- if (user == null) {
- throw new UiLogicError('You must login to perform the operation.');
- }
- return user;
-}
-
-export class UserNotExistError extends Error {}
-
-export class UserInfoService {
- async saveUser(user: HttpUser): Promise<void> {
- const key = user.username;
- const line = this._userHub.getLineOrCreateWithoutSetup(key);
- if (line.isSyncing) return;
- line.beginSync();
- await this.doSaveUser(user);
- line.endSyncAndNext({ user, type: 'synced' });
- }
-
- private getCachedUser(username: string): Promise<User | null> {
- return dataStorage.getItem<HttpUser | null>(`user.${username}`);
- }
-
- private doSaveUser(user: HttpUser): Promise<void> {
- return dataStorage.setItem<HttpUser>(`user.${user.username}`, user).then();
- }
-
- private async syncUser(username: string): Promise<void> {
- const line = this._userHub.getLineOrCreateWithoutSetup(username);
- if (line.isSyncing) return;
- line.beginSync();
-
- if (line.value == undefined) {
- const cache = await this.getCachedUser(username);
- if (cache != null) {
- line.next({ user: cache, type: 'cache' });
- }
- }
-
- try {
- const res = await getHttpUserClient().get(username);
- await this.doSaveUser(res);
- line.endSyncAndNext({ user: res, type: 'synced' });
- } catch (e) {
- if (e instanceof HttpUserNotExistError) {
- line.endSyncAndNext({ type: 'notexist' });
- } else {
- const cache = await this.getCachedUser(username);
- line.endSyncAndNext({ user: cache ?? undefined, type: 'offline' });
- throwIfNotNetworkError(e);
- }
- }
- }
-
- private _userHub = new DataHub<
- string,
- | { user: User; type: 'cache' | 'synced' | 'offline' }
- | { user?: undefined; type: 'notexist' | 'offline' }
- >({
- setup: (key) => {
- void this.syncUser(key);
- },
- });
-
- getUser$(username: string): Observable<User> {
- return this._userHub.getObservable(username).pipe(
- map((state) => state?.user),
- filter((user): user is User => user != null)
- );
- }
-
- private getCachedAvatar(username: string): Promise<BlobWithEtag | null> {
- return dataStorage.getItem<BlobWithEtag | null>(`user.${username}.avatar`);
- }
-
- private saveAvatar(username: string, data: BlobWithEtag): Promise<void> {
- return dataStorage
- .setItem<BlobWithEtag>(`user.${username}.avatar`, data)
- .then();
- }
-
- private async syncAvatar(username: string): Promise<void> {
- const line = this._avatarHub.getLineOrCreateWithoutSetup(username);
- if (line.isSyncing) return;
- line.beginSync();
-
- const cache = await this.getCachedAvatar(username);
- if (line.value == null) {
- if (cache != null) {
- line.next({ data: cache.data, type: 'cache' });
- }
- }
-
- if (cache == null) {
- try {
- const avatar = await getHttpUserClient().getAvatar(username);
- await this.saveAvatar(username, avatar);
- line.endSyncAndNext({ data: avatar.data, type: 'synced' });
- } catch (e) {
- line.endSyncAndNext({ type: 'offline' });
- throwIfNotNetworkError(e);
- }
- } else {
- try {
- const res = await getHttpUserClient().getAvatar(username, cache.etag);
- if (res instanceof NotModified) {
- line.endSyncAndNext({ data: cache.data, type: 'synced' });
- } else {
- const avatar = res;
- await this.saveAvatar(username, avatar);
- line.endSyncAndNext({ data: avatar.data, type: 'synced' });
- }
- } catch (e) {
- line.endSyncAndNext({ data: cache.data, type: 'offline' });
- throwIfNotNetworkError(e);
- }
- }
- }
-
- private _avatarHub = new DataHub<
- string,
- | { data: Blob; type: 'cache' | 'synced' | 'offline' }
- | { data?: undefined; type: 'notexist' | 'offline' }
- >({
- setup: (key) => {
- void this.syncAvatar(key);
- },
- });
-
- getAvatar$(username: string): Observable<Blob> {
- return this._avatarHub.getObservable(username).pipe(
- map((state) => state.data),
- filter((blob): blob is Blob => blob != null)
- );
- }
-
- getUserInfo(username: string): Observable<User> {
- return from(getHttpUserClient().get(username)).pipe(
- convertError(HttpUserNotExistError, UserNotExistError)
- );
- }
-
- async setAvatar(username: string, blob: Blob): Promise<void> {
- const user = checkLogin();
- await getHttpUserClient().putAvatar(username, blob, user.token);
- this._avatarHub.getLine(username)?.next({ data: blob, type: 'synced' });
- }
-}
-
-export const userInfoService = new UserInfoService();
-
-export function useAvatar(username?: string): Blob | undefined {
- const [state, setState] = React.useState<Blob | undefined>(undefined);
- React.useEffect(() => {
- if (username == null) {
- setState(undefined);
- return;
- }
-
- const subscription = userInfoService
- .getAvatar$(username)
- .subscribe((blob) => {
- setState(blob);
- });
- return () => {
- subscription.unsubscribe();
- };
- }, [username]);
- return state;
-}
+import React, { useState, useEffect } from "react"; +import { BehaviorSubject, Observable, from } from "rxjs"; +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, + HttpCreateTokenBadCredentialError, +} from "../http/token"; +import { + getHttpUserClient, + HttpUserNotExistError, + HttpUser, +} from "../http/user"; + +export type User = HttpUser; + +export interface UserAuthInfo { + username: string; + administrator: boolean; +} + +export interface UserWithToken extends User { + token: string; +} + +export interface LoginCredentials { + username: string; + password: string; +} + +export class BadCredentialError { + message = "login.badCredential"; +} + +const USER_STORAGE_KEY = "currentuser"; + +export class UserService { + private userSubject = new BehaviorSubject<UserWithToken | null | undefined>( + undefined + ); + + get user$(): Observable<UserWithToken | null | undefined> { + return this.userSubject; + } + + get currentUser(): UserWithToken | null | undefined { + return this.userSubject.value; + } + + async checkLoginState(): Promise<UserWithToken | null> { + if (this.currentUser !== undefined) { + console.warn("Already checked user. Can't check twice."); + } + + const savedUser = await dataStorage.getItem<UserWithToken | null>( + USER_STORAGE_KEY + ); + + if (savedUser == null) { + this.userSubject.next(null); + return null; + } + + this.userSubject.next(savedUser); + + const savedToken = savedUser.token; + try { + const res = await getHttpTokenClient().verify({ token: savedToken }); + const user: UserWithToken = { ...res.user, token: savedToken }; + await dataStorage.setItem<UserWithToken>(USER_STORAGE_KEY, user); + this.userSubject.next(user); + pushAlert({ + type: "success", + message: { + type: "i18n", + key: "user.welcomeBack", + }, + }); + return user; + } catch (error) { + if (error instanceof HttpNetworkError) { + pushAlert({ + type: "danger", + message: { type: "i18n", key: "user.verifyTokenFailedNetwork" }, + }); + return savedUser; + } else { + await dataStorage.removeItem(USER_STORAGE_KEY); + this.userSubject.next(null); + pushAlert({ + type: "danger", + message: { type: "i18n", key: "user.verifyTokenFailed" }, + }); + return null; + } + } + } + + async login( + credentials: LoginCredentials, + rememberMe: boolean + ): Promise<void> { + if (this.currentUser) { + throw new UiLogicError("Already login."); + } + try { + const res = await getHttpTokenClient().create({ + ...credentials, + expire: 30, + }); + const user: UserWithToken = { + ...res.user, + token: res.token, + }; + if (rememberMe) { + await dataStorage.setItem<UserWithToken>(USER_STORAGE_KEY, user); + } + this.userSubject.next(user); + } catch (e) { + if (e instanceof HttpCreateTokenBadCredentialError) { + throw new BadCredentialError(); + } else { + throw e; + } + } + } + + async logout(): Promise<void> { + if (this.currentUser === undefined) { + throw new UiLogicError("Please check user first."); + } + if (this.currentUser === null) { + throw new UiLogicError("No login."); + } + await dataStorage.removeItem(USER_STORAGE_KEY); + this.userSubject.next(null); + } + + changePassword( + oldPassword: string, + newPassword: string + ): Observable<unknown> { + if (this.currentUser == undefined) { + throw new UiLogicError("Not login or checked now, can't log out."); + } + const $ = from( + getHttpUserClient().changePassword( + { + oldPassword, + newPassword, + }, + this.currentUser.token + ) + ); + $.subscribe(() => { + void this.logout(); + }); + return $; + } +} + +export const userService = new UserService(); + +export function useRawUser(): UserWithToken | null | undefined { + const [user, setUser] = useState<UserWithToken | null | undefined>( + userService.currentUser + ); + useEffect(() => { + const subscription = userService.user$.subscribe((u) => setUser(u)); + return () => { + subscription.unsubscribe(); + }; + }); + return user; +} + +export function useUser(): UserWithToken | null { + const [user, setUser] = useState<UserWithToken | null>(() => { + const initUser = userService.currentUser; + if (initUser === undefined) { + throw new UiLogicError( + "This is a logic error in user module. Current user can't be undefined in useUser." + ); + } + return initUser; + }); + useEffect(() => { + const sub = userService.user$.subscribe((u) => { + if (u === undefined) { + throw new UiLogicError( + "This is a logic error in user module. User emitted can't be undefined later." + ); + } + setUser(u); + }); + return () => { + sub.unsubscribe(); + }; + }); + return user; +} + +export function useUserLoggedIn(): UserWithToken { + const user = useUser(); + if (user == null) { + throw new UiLogicError("You assert user has logged in but actually not."); + } + return user; +} + +export function checkLogin(): UserWithToken { + const user = userService.currentUser; + if (user == null) { + throw new UiLogicError("You must login to perform the operation."); + } + return user; +} + +export class UserNotExistError extends Error {} + +export class UserInfoService { + async saveUser(user: HttpUser): Promise<void> { + const key = user.username; + const line = this._userHub.getLineOrCreateWithoutSetup(key); + if (line.isSyncing) return; + line.beginSync(); + await this.doSaveUser(user); + line.endSyncAndNext({ user, type: "synced" }); + } + + private getCachedUser(username: string): Promise<User | null> { + return dataStorage.getItem<HttpUser | null>(`user.${username}`); + } + + private doSaveUser(user: HttpUser): Promise<void> { + return dataStorage.setItem<HttpUser>(`user.${user.username}`, user).then(); + } + + private async syncUser(username: string): Promise<void> { + const line = this._userHub.getLineOrCreateWithoutSetup(username); + if (line.isSyncing) return; + line.beginSync(); + + if (line.value == undefined) { + const cache = await this.getCachedUser(username); + if (cache != null) { + line.next({ user: cache, type: "cache" }); + } + } + + try { + const res = await getHttpUserClient().get(username); + await this.doSaveUser(res); + line.endSyncAndNext({ user: res, type: "synced" }); + } catch (e) { + if (e instanceof HttpUserNotExistError) { + line.endSyncAndNext({ type: "notexist" }); + } else { + const cache = await this.getCachedUser(username); + line.endSyncAndNext({ user: cache ?? undefined, type: "offline" }); + throwIfNotNetworkError(e); + } + } + } + + private _userHub = new DataHub< + string, + | { user: User; type: "cache" | "synced" | "offline" } + | { user?: undefined; type: "notexist" | "offline" } + >({ + setup: (key) => { + void this.syncUser(key); + }, + }); + + getUser$(username: string): Observable<User> { + return this._userHub.getObservable(username).pipe( + map((state) => state?.user), + filter((user): user is User => user != null) + ); + } + + private getCachedAvatar(username: string): Promise<BlobWithEtag | null> { + return dataStorage.getItem<BlobWithEtag | null>(`user.${username}.avatar`); + } + + private saveAvatar(username: string, data: BlobWithEtag): Promise<void> { + return dataStorage + .setItem<BlobWithEtag>(`user.${username}.avatar`, data) + .then(); + } + + private async syncAvatar(username: string): Promise<void> { + const line = this._avatarHub.getLineOrCreateWithoutSetup(username); + if (line.isSyncing) return; + line.beginSync(); + + const cache = await this.getCachedAvatar(username); + if (line.value == null) { + if (cache != null) { + line.next({ data: cache.data, type: "cache" }); + } + } + + if (cache == null) { + try { + const avatar = await getHttpUserClient().getAvatar(username); + await this.saveAvatar(username, avatar); + line.endSyncAndNext({ data: avatar.data, type: "synced" }); + } catch (e) { + line.endSyncAndNext({ type: "offline" }); + throwIfNotNetworkError(e); + } + } else { + try { + const res = await getHttpUserClient().getAvatar(username, cache.etag); + if (res instanceof NotModified) { + line.endSyncAndNext({ data: cache.data, type: "synced" }); + } else { + const avatar = res; + await this.saveAvatar(username, avatar); + line.endSyncAndNext({ data: avatar.data, type: "synced" }); + } + } catch (e) { + line.endSyncAndNext({ data: cache.data, type: "offline" }); + throwIfNotNetworkError(e); + } + } + } + + private _avatarHub = new DataHub< + string, + | { data: Blob; type: "cache" | "synced" | "offline" } + | { data?: undefined; type: "notexist" | "offline" } + >({ + setup: (key) => { + void this.syncAvatar(key); + }, + }); + + getAvatar$(username: string): Observable<Blob> { + return this._avatarHub.getObservable(username).pipe( + map((state) => state.data), + filter((blob): blob is Blob => blob != null) + ); + } + + getUserInfo(username: string): Observable<User> { + return from(getHttpUserClient().get(username)).pipe( + convertError(HttpUserNotExistError, UserNotExistError) + ); + } + + async setAvatar(username: string, blob: Blob): Promise<void> { + const user = checkLogin(); + await getHttpUserClient().putAvatar(username, blob, user.token); + this._avatarHub.getLine(username)?.next({ data: blob, type: "synced" }); + } +} + +export const userInfoService = new UserInfoService(); + +export function useAvatar(username?: string): Blob | undefined { + const [state, setState] = React.useState<Blob | undefined>(undefined); + React.useEffect(() => { + if (username == null) { + setState(undefined); + return; + } + + const subscription = userInfoService + .getAvatar$(username) + .subscribe((blob) => { + setState(blob); + }); + return () => { + subscription.unsubscribe(); + }; + }, [username]); + return state; +} diff --git a/Timeline/ClientApp/src/app/home/BoardWithUser.tsx b/Timeline/ClientApp/src/app/home/BoardWithUser.tsx index 3830104f..4910aebe 100644 --- a/Timeline/ClientApp/src/app/home/BoardWithUser.tsx +++ b/Timeline/ClientApp/src/app/home/BoardWithUser.tsx @@ -1,102 +1,102 @@ -import React from 'react';
-import { Row, Col } from 'reactstrap';
-import { useTranslation } from 'react-i18next';
-
-import { UserWithToken } from '../data/user';
-import { TimelineInfo } from '../data/timeline';
-
-import { getHttpTimelineClient } from '../http/timeline';
-
-import TimelineBoard from './TimelineBoard';
-import OfflineBoard from './OfflineBoard';
-
-const BoardWithUser: React.FC<{ user: UserWithToken }> = ({ user }) => {
- const { t } = useTranslation();
-
- const [ownTimelines, setOwnTimelines] = React.useState<
- TimelineInfo[] | 'offline' | 'loading'
- >('loading');
- const [joinTimelines, setJoinTimelines] = React.useState<
- TimelineInfo[] | 'offline' | 'loading'
- >('loading');
-
- React.useEffect(() => {
- let subscribe = true;
- if (ownTimelines === 'loading') {
- void getHttpTimelineClient()
- .listTimeline({ relate: user.username, relateType: 'own' })
- .then(
- (timelines) => {
- if (subscribe) {
- setOwnTimelines(timelines);
- }
- },
- () => {
- setOwnTimelines('offline');
- }
- );
- }
- return () => {
- subscribe = false;
- };
- }, [user, ownTimelines]);
-
- React.useEffect(() => {
- let subscribe = true;
- if (joinTimelines === 'loading') {
- void getHttpTimelineClient()
- .listTimeline({ relate: user.username, relateType: 'join' })
- .then(
- (timelines) => {
- if (subscribe) {
- setJoinTimelines(timelines);
- }
- },
- () => {
- setJoinTimelines('offline');
- }
- );
- }
- return () => {
- subscribe = false;
- };
- }, [user, joinTimelines]);
-
- return (
- <Row className="my-2 justify-content-center">
- {ownTimelines === 'offline' && joinTimelines === 'offline' ? (
- <Col className="py-2" sm="8" lg="6">
- <OfflineBoard
- onReload={() => {
- setOwnTimelines('loading');
- setJoinTimelines('loading');
- }}
- />
- </Col>
- ) : (
- <>
- <Col sm="6" lg="5" className="py-2">
- <TimelineBoard
- title={t('home.ownTimeline')}
- timelines={ownTimelines}
- onReload={() => {
- setOwnTimelines('loading');
- }}
- />
- </Col>
- <Col sm="6" lg="5" className="py-2">
- <TimelineBoard
- title={t('home.joinTimeline')}
- timelines={joinTimelines}
- onReload={() => {
- setJoinTimelines('loading');
- }}
- />
- </Col>
- </>
- )}
- </Row>
- );
-};
-
-export default BoardWithUser;
+import React from "react"; +import { Row, Col } from "reactstrap"; +import { useTranslation } from "react-i18next"; + +import { UserWithToken } from "../data/user"; +import { TimelineInfo } from "../data/timeline"; + +import { getHttpTimelineClient } from "../http/timeline"; + +import TimelineBoard from "./TimelineBoard"; +import OfflineBoard from "./OfflineBoard"; + +const BoardWithUser: React.FC<{ user: UserWithToken }> = ({ user }) => { + const { t } = useTranslation(); + + const [ownTimelines, setOwnTimelines] = React.useState< + TimelineInfo[] | "offline" | "loading" + >("loading"); + const [joinTimelines, setJoinTimelines] = React.useState< + TimelineInfo[] | "offline" | "loading" + >("loading"); + + React.useEffect(() => { + let subscribe = true; + if (ownTimelines === "loading") { + void getHttpTimelineClient() + .listTimeline({ relate: user.username, relateType: "own" }) + .then( + (timelines) => { + if (subscribe) { + setOwnTimelines(timelines); + } + }, + () => { + setOwnTimelines("offline"); + } + ); + } + return () => { + subscribe = false; + }; + }, [user, ownTimelines]); + + React.useEffect(() => { + let subscribe = true; + if (joinTimelines === "loading") { + void getHttpTimelineClient() + .listTimeline({ relate: user.username, relateType: "join" }) + .then( + (timelines) => { + if (subscribe) { + setJoinTimelines(timelines); + } + }, + () => { + setJoinTimelines("offline"); + } + ); + } + return () => { + subscribe = false; + }; + }, [user, joinTimelines]); + + return ( + <Row className="my-2 justify-content-center"> + {ownTimelines === "offline" && joinTimelines === "offline" ? ( + <Col className="py-2" sm="8" lg="6"> + <OfflineBoard + onReload={() => { + setOwnTimelines("loading"); + setJoinTimelines("loading"); + }} + /> + </Col> + ) : ( + <> + <Col sm="6" lg="5" className="py-2"> + <TimelineBoard + title={t("home.ownTimeline")} + timelines={ownTimelines} + onReload={() => { + setOwnTimelines("loading"); + }} + /> + </Col> + <Col sm="6" lg="5" className="py-2"> + <TimelineBoard + title={t("home.joinTimeline")} + timelines={joinTimelines} + onReload={() => { + setJoinTimelines("loading"); + }} + /> + </Col> + </> + )} + </Row> + ); +}; + +export default BoardWithUser; diff --git a/Timeline/ClientApp/src/app/home/BoardWithoutUser.tsx b/Timeline/ClientApp/src/app/home/BoardWithoutUser.tsx index 4b30fcc4..a7dc36be 100644 --- a/Timeline/ClientApp/src/app/home/BoardWithoutUser.tsx +++ b/Timeline/ClientApp/src/app/home/BoardWithoutUser.tsx @@ -1,61 +1,61 @@ -import React from 'react';
-import { Row, Col } from 'reactstrap';
-
-import { TimelineInfo } from '../data/timeline';
-
-import { getHttpTimelineClient } from '../http/timeline';
-
-import TimelineBoard from './TimelineBoard';
-import OfflineBoard from './OfflineBoard';
-
-const BoardWithoutUser: React.FC = () => {
- const [publicTimelines, setPublicTimelines] = React.useState<
- TimelineInfo[] | 'offline' | 'loading'
- >('loading');
-
- React.useEffect(() => {
- let subscribe = true;
- if (publicTimelines === 'loading') {
- void getHttpTimelineClient()
- .listTimeline({ visibility: 'Public' })
- .then(
- (timelines) => {
- if (subscribe) {
- setPublicTimelines(timelines);
- }
- },
- () => {
- setPublicTimelines('offline');
- }
- );
- }
- return () => {
- subscribe = false;
- };
- }, [publicTimelines]);
-
- return (
- <Row className="my-2 justify-content-center">
- {publicTimelines === 'offline' ? (
- <Col sm="8" lg="6">
- <OfflineBoard
- onReload={() => {
- setPublicTimelines('loading');
- }}
- />
- </Col>
- ) : (
- <Col sm="8" lg="6">
- <TimelineBoard
- timelines={publicTimelines}
- onReload={() => {
- setPublicTimelines('loading');
- }}
- />
- </Col>
- )}
- </Row>
- );
-};
-
-export default BoardWithoutUser;
+import React from "react"; +import { Row, Col } from "reactstrap"; + +import { TimelineInfo } from "../data/timeline"; + +import { getHttpTimelineClient } from "../http/timeline"; + +import TimelineBoard from "./TimelineBoard"; +import OfflineBoard from "./OfflineBoard"; + +const BoardWithoutUser: React.FC = () => { + const [publicTimelines, setPublicTimelines] = React.useState< + TimelineInfo[] | "offline" | "loading" + >("loading"); + + React.useEffect(() => { + let subscribe = true; + if (publicTimelines === "loading") { + void getHttpTimelineClient() + .listTimeline({ visibility: "Public" }) + .then( + (timelines) => { + if (subscribe) { + setPublicTimelines(timelines); + } + }, + () => { + setPublicTimelines("offline"); + } + ); + } + return () => { + subscribe = false; + }; + }, [publicTimelines]); + + return ( + <Row className="my-2 justify-content-center"> + {publicTimelines === "offline" ? ( + <Col sm="8" lg="6"> + <OfflineBoard + onReload={() => { + setPublicTimelines("loading"); + }} + /> + </Col> + ) : ( + <Col sm="8" lg="6"> + <TimelineBoard + timelines={publicTimelines} + onReload={() => { + setPublicTimelines("loading"); + }} + /> + </Col> + )} + </Row> + ); +}; + +export default BoardWithoutUser; diff --git a/Timeline/ClientApp/src/app/home/Home.tsx b/Timeline/ClientApp/src/app/home/Home.tsx index b759fa50..00e6ff5a 100644 --- a/Timeline/ClientApp/src/app/home/Home.tsx +++ b/Timeline/ClientApp/src/app/home/Home.tsx @@ -1,102 +1,102 @@ -import React from 'react';
-import { useHistory } from 'react-router';
-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';
-
-const Home: React.FC = () => {
- const history = useHistory();
-
- const { t } = useTranslation();
-
- const user = useUser();
-
- const [navText, setNavText] = React.useState<string>('');
-
- const [dialog, setDialog] = React.useState<'create' | null>(null);
-
- const goto = React.useCallback((): void => {
- if (navText === '') {
- history.push('users/crupest');
- } else if (navText.startsWith('@')) {
- history.push(`users/${navText.slice(1)}`);
- } else {
- history.push(`timelines/${navText}`);
- }
- }, [navText, history]);
-
- return (
- <>
- <AppBar />
- <Container fluid style={{ marginTop: '56px' }}>
- <Row>
- <Col>
- <SearchInput
- className="justify-content-center"
- value={navText}
- onChange={setNavText}
- onButtonClick={goto}
- buttonText={t('home.go')}
- placeholder="@crupest"
- additionalButton={
- user != null && (
- <Button
- color="success"
- outline
- onClick={() => {
- setDialog('create');
- }}
- >
- {t('home.createButton')}
- </Button>
- )
- }
- />
- </Col>
- </Row>
- {(() => {
- if (user == null) {
- return <BoardWithoutUser />;
- } else {
- return <BoardWithUser user={user} />;
- }
- })()}
- </Container>
- <footer className="text-right">
- <a
- className="mx-3 text-muted"
- href="http://beian.miit.gov.cn/"
- target="_blank"
- rel="noopener noreferrer"
- >
- <small>鄂ICP备18030913号-1</small>
- </a>
- <a
- className="mx-3 text-muted"
- href="http://www.beian.gov.cn/"
- target="_blank"
- rel="noopener noreferrer"
- >
- <small className="white-space-no-wrap">公安备案 42112102000124</small>
- </a>
- </footer>
- {dialog === 'create' && (
- <TimelineCreateDialog
- open
- close={() => {
- setDialog(null);
- }}
- />
- )}
- </>
- );
-};
-
-export default Home;
+import React from "react"; +import { useHistory } from "react-router"; +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"; + +const Home: React.FC = () => { + const history = useHistory(); + + const { t } = useTranslation(); + + const user = useUser(); + + const [navText, setNavText] = React.useState<string>(""); + + const [dialog, setDialog] = React.useState<"create" | null>(null); + + const goto = React.useCallback((): void => { + if (navText === "") { + history.push("users/crupest"); + } else if (navText.startsWith("@")) { + history.push(`users/${navText.slice(1)}`); + } else { + history.push(`timelines/${navText}`); + } + }, [navText, history]); + + return ( + <> + <AppBar /> + <Container fluid style={{ marginTop: "56px" }}> + <Row> + <Col> + <SearchInput + className="justify-content-center" + value={navText} + onChange={setNavText} + onButtonClick={goto} + buttonText={t("home.go")} + placeholder="@crupest" + additionalButton={ + user != null && ( + <Button + color="success" + outline + onClick={() => { + setDialog("create"); + }} + > + {t("home.createButton")} + </Button> + ) + } + /> + </Col> + </Row> + {(() => { + if (user == null) { + return <BoardWithoutUser />; + } else { + return <BoardWithUser user={user} />; + } + })()} + </Container> + <footer className="text-right"> + <a + className="mx-3 text-muted" + href="http://beian.miit.gov.cn/" + target="_blank" + rel="noopener noreferrer" + > + <small>鄂ICP备18030913号-1</small> + </a> + <a + className="mx-3 text-muted" + href="http://www.beian.gov.cn/" + target="_blank" + rel="noopener noreferrer" + > + <small className="white-space-no-wrap">公安备案 42112102000124</small> + </a> + </footer> + {dialog === "create" && ( + <TimelineCreateDialog + open + close={() => { + setDialog(null); + }} + /> + )} + </> + ); +}; + +export default Home; diff --git a/Timeline/ClientApp/src/app/home/OfflineBoard.tsx b/Timeline/ClientApp/src/app/home/OfflineBoard.tsx index ca6d2a26..458166ac 100644 --- a/Timeline/ClientApp/src/app/home/OfflineBoard.tsx +++ b/Timeline/ClientApp/src/app/home/OfflineBoard.tsx @@ -1,62 +1,62 @@ -import React from 'react';
-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';
-
-export interface OfflineBoardProps {
- onReload: () => void;
-}
-
-const OfflineBoard: React.FC<OfflineBoardProps> = ({ onReload }) => {
- const [timelines, setTimelines] = React.useState<string[]>([]);
-
- React.useEffect(() => {
- let subscribe = true;
- void getAllCachedTimelineNames().then((t) => {
- if (subscribe) setTimelines(t);
- });
- return () => {
- subscribe = false;
- };
- });
-
- return (
- <>
- <Trans i18nKey="home.offlinePrompt">
- 0
- <a
- href="#"
- onClick={(e) => {
- onReload();
- e.preventDefault();
- }}
- >
- 1
- </a>
- 2
- </Trans>
- {timelines.map((timeline) => {
- const isPersonal = timeline.startsWith('@');
- const url = isPersonal
- ? `/users/${timeline.slice(1)}`
- : `/timelines/${timeline}`;
- return (
- <div key={timeline} className="timeline-board-item">
- {isPersonal ? (
- <UserTimelineLogo className="icon" />
- ) : (
- <TimelineLogo className="icon" />
- )}
- <Link to={url}>{timeline}</Link>
- </div>
- );
- })}
- </>
- );
-};
-
-export default OfflineBoard;
+import React from "react"; +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"; + +export interface OfflineBoardProps { + onReload: () => void; +} + +const OfflineBoard: React.FC<OfflineBoardProps> = ({ onReload }) => { + const [timelines, setTimelines] = React.useState<string[]>([]); + + React.useEffect(() => { + let subscribe = true; + void getAllCachedTimelineNames().then((t) => { + if (subscribe) setTimelines(t); + }); + return () => { + subscribe = false; + }; + }); + + return ( + <> + <Trans i18nKey="home.offlinePrompt"> + 0 + <a + href="#" + onClick={(e) => { + onReload(); + e.preventDefault(); + }} + > + 1 + </a> + 2 + </Trans> + {timelines.map((timeline) => { + const isPersonal = timeline.startsWith("@"); + const url = isPersonal + ? `/users/${timeline.slice(1)}` + : `/timelines/${timeline}`; + return ( + <div key={timeline} className="timeline-board-item"> + {isPersonal ? ( + <UserTimelineLogo className="icon" /> + ) : ( + <TimelineLogo className="icon" /> + )} + <Link to={url}>{timeline}</Link> + </div> + ); + })} + </> + ); +}; + +export default OfflineBoard; diff --git a/Timeline/ClientApp/src/app/home/TimelineBoard.tsx b/Timeline/ClientApp/src/app/home/TimelineBoard.tsx index 8f8f6387..91bf2b77 100644 --- a/Timeline/ClientApp/src/app/home/TimelineBoard.tsx +++ b/Timeline/ClientApp/src/app/home/TimelineBoard.tsx @@ -1,74 +1,74 @@ -import React from 'react';
-import clsx from 'clsx';
-import { Link } from 'react-router-dom';
-import { Spinner } from 'reactstrap';
-import { Trans } from 'react-i18next';
-
-import { TimelineInfo } from '../data/timeline';
-
-import TimelineLogo from '../common/TimelineLogo';
-import UserTimelineLogo from '../common/UserTimelineLogo';
-
-export interface TimelineBoardProps {
- title?: string;
- timelines: TimelineInfo[] | 'offline' | 'loading';
- onReload: () => void;
- className?: string;
-}
-
-const TimelineBoard: React.FC<TimelineBoardProps> = (props) => {
- const { title, timelines, className } = props;
-
- return (
- <div className={clsx('timeline-board', className)}>
- {title != null && <h3 className="text-center">{title}</h3>}
- {(() => {
- if (timelines === 'loading') {
- return (
- <div className="d-flex flex-grow-1 justify-content-center align-items-center">
- <Spinner color="primary" />
- </div>
- );
- } else if (timelines === 'offline') {
- return (
- <div className="d-flex flex-grow-1 justify-content-center align-items-center">
- <Trans i18nKey="loadFailReload" parent="div">
- 0
- <a
- href="#"
- onClick={(e) => {
- props.onReload();
- e.preventDefault();
- }}
- >
- 1
- </a>
- 2
- </Trans>
- </div>
- );
- } else {
- return timelines.map((timeline) => {
- const { name } = timeline;
- const isPersonal = name.startsWith('@');
- const url = isPersonal
- ? `/users/${timeline.owner.username}`
- : `/timelines/${name}`;
- return (
- <div key={name} className="timeline-board-item">
- {isPersonal ? (
- <UserTimelineLogo className="icon" />
- ) : (
- <TimelineLogo className="icon" />
- )}
- <Link to={url}>{name}</Link>
- </div>
- );
- });
- }
- })()}
- </div>
- );
-};
-
-export default TimelineBoard;
+import React from "react"; +import clsx from "clsx"; +import { Link } from "react-router-dom"; +import { Spinner } from "reactstrap"; +import { Trans } from "react-i18next"; + +import { TimelineInfo } from "../data/timeline"; + +import TimelineLogo from "../common/TimelineLogo"; +import UserTimelineLogo from "../common/UserTimelineLogo"; + +export interface TimelineBoardProps { + title?: string; + timelines: TimelineInfo[] | "offline" | "loading"; + onReload: () => void; + className?: string; +} + +const TimelineBoard: React.FC<TimelineBoardProps> = (props) => { + const { title, timelines, className } = props; + + return ( + <div className={clsx("timeline-board", className)}> + {title != null && <h3 className="text-center">{title}</h3>} + {(() => { + if (timelines === "loading") { + return ( + <div className="d-flex flex-grow-1 justify-content-center align-items-center"> + <Spinner color="primary" /> + </div> + ); + } else if (timelines === "offline") { + return ( + <div className="d-flex flex-grow-1 justify-content-center align-items-center"> + <Trans i18nKey="loadFailReload" parent="div"> + 0 + <a + href="#" + onClick={(e) => { + props.onReload(); + e.preventDefault(); + }} + > + 1 + </a> + 2 + </Trans> + </div> + ); + } else { + return timelines.map((timeline) => { + const { name } = timeline; + const isPersonal = name.startsWith("@"); + const url = isPersonal + ? `/users/${timeline.owner.username}` + : `/timelines/${name}`; + return ( + <div key={name} className="timeline-board-item"> + {isPersonal ? ( + <UserTimelineLogo className="icon" /> + ) : ( + <TimelineLogo className="icon" /> + )} + <Link to={url}>{name}</Link> + </div> + ); + }); + } + })()} + </div> + ); +}; + +export default TimelineBoard; diff --git a/Timeline/ClientApp/src/app/home/TimelineCreateDialog.tsx b/Timeline/ClientApp/src/app/home/TimelineCreateDialog.tsx index 06f908f9..c5ba64e7 100644 --- a/Timeline/ClientApp/src/app/home/TimelineCreateDialog.tsx +++ b/Timeline/ClientApp/src/app/home/TimelineCreateDialog.tsx @@ -1,54 +1,54 @@ -import React from 'react';
-import { useHistory } from 'react-router';
-
-import { validateTimelineName, timelineService } from '../data/timeline';
-
-import OperationDialog from '../common/OperationDialog';
-
-interface TimelineCreateDialogProps {
- open: boolean;
- close: () => void;
-}
-
-const TimelineCreateDialog: React.FC<TimelineCreateDialogProps> = (props) => {
- const history = useHistory();
-
- let nameSaved: string;
-
- return (
- <OperationDialog
- open={props.open}
- close={props.close}
- titleColor="success"
- title="home.createDialog.title"
- inputScheme={[
- {
- type: 'text',
- label: 'home.createDialog.name',
- helperText: 'home.createDialog.nameFormat',
- validator: (name) => {
- if (name.length === 0) {
- return 'home.createDialog.noEmpty';
- } else if (name.length > 26) {
- return 'home.createDialog.tooLong';
- } else if (!validateTimelineName(name)) {
- return 'home.createDialog.badFormat';
- } else {
- return null;
- }
- },
- },
- ]}
- onProcess={([name]) => {
- nameSaved = name as string;
- return timelineService.createTimeline(nameSaved).toPromise();
- }}
- onSuccessAndClose={() => {
- history.push(`timelines/${nameSaved}`);
- }}
- failurePrompt={(e) => `${e as string}`}
- />
- );
-};
-
-export default TimelineCreateDialog;
+import React from "react"; +import { useHistory } from "react-router"; + +import { validateTimelineName, timelineService } from "../data/timeline"; + +import OperationDialog from "../common/OperationDialog"; + +interface TimelineCreateDialogProps { + open: boolean; + close: () => void; +} + +const TimelineCreateDialog: React.FC<TimelineCreateDialogProps> = (props) => { + const history = useHistory(); + + let nameSaved: string; + + return ( + <OperationDialog + open={props.open} + close={props.close} + titleColor="success" + title="home.createDialog.title" + inputScheme={[ + { + type: "text", + label: "home.createDialog.name", + helperText: "home.createDialog.nameFormat", + validator: (name) => { + if (name.length === 0) { + return "home.createDialog.noEmpty"; + } else if (name.length > 26) { + return "home.createDialog.tooLong"; + } else if (!validateTimelineName(name)) { + return "home.createDialog.badFormat"; + } else { + return null; + } + }, + }, + ]} + onProcess={([name]) => { + nameSaved = name as string; + return timelineService.createTimeline(nameSaved).toPromise(); + }} + onSuccessAndClose={() => { + history.push(`timelines/${nameSaved}`); + }} + failurePrompt={(e) => `${e as string}`} + /> + ); +}; + +export default TimelineCreateDialog; diff --git a/Timeline/ClientApp/src/app/home/home.sass b/Timeline/ClientApp/src/app/home/home.sass index 28a2e5f3..f5d6ffc3 100644 --- a/Timeline/ClientApp/src/app/home/home.sass +++ b/Timeline/ClientApp/src/app/home/home.sass @@ -1,13 +1,13 @@ -.timeline-board-item
- font-size: 1.1em
- @extend .my-2
- .icon
- height: 1.3em
- @extend .mr-2
-
-.timeline-board
- @extend .cru-card
- @extend .d-flex
- @extend .flex-column
- @extend .p-3
- min-height: 200px
+.timeline-board-item + font-size: 1.1em + @extend .my-2 + .icon + height: 1.3em + @extend .mr-2 + +.timeline-board + @extend .cru-card + @extend .d-flex + @extend .flex-column + @extend .p-3 + min-height: 200px diff --git a/Timeline/ClientApp/src/app/http/common.ts b/Timeline/ClientApp/src/app/http/common.ts index 1f904106..54203d1a 100644 --- a/Timeline/ClientApp/src/app/http/common.ts +++ b/Timeline/ClientApp/src/app/http/common.ts @@ -1,161 +1,161 @@ -import { AxiosError, AxiosResponse } from 'axios';
-
-export const apiBaseUrl = '/api';
-
-export function base64(blob: Blob): Promise<string> {
- return new Promise<string>((resolve) => {
- const reader = new FileReader();
- reader.onload = function () {
- resolve((reader.result as string).replace(/^data:.+;base64,/, ''));
- };
- reader.readAsDataURL(blob);
- });
-}
-
-export function extractStatusCode(error: AxiosError): number | null {
- if (error.isAxiosError) {
- const code = error?.response?.status;
- if (typeof code === 'number') {
- return code;
- }
- }
- return null;
-}
-
-export interface CommonErrorResponse {
- code: number;
- message: string;
-}
-
-export function extractErrorCode(
- error: AxiosError<CommonErrorResponse>
-): number | null {
- if (error.isAxiosError) {
- const code = error.response?.data?.code;
- if (typeof code === 'number') {
- return code;
- }
- }
- return null;
-}
-
-export class HttpNetworkError extends Error {
- constructor(public innerError?: AxiosError) {
- super();
- }
-}
-
-export class HttpForbiddenError extends Error {
- constructor(public innerError?: AxiosError) {
- super();
- }
-}
-
-export class NotModified {}
-
-export interface BlobWithEtag {
- data: Blob;
- etag: string;
-}
-
-export function extractResponseData<T>(res: AxiosResponse<T>): T {
- return res.data;
-}
-
-export function catchIfStatusCodeIs<
- TResult,
- TErrorHandlerResult extends TResult | PromiseLike<TResult> | null | undefined
->(
- statusCode: number,
- errorHandler: (error: AxiosError<CommonErrorResponse>) => TErrorHandlerResult
-): (error: AxiosError<CommonErrorResponse>) => TErrorHandlerResult {
- return (error: AxiosError<CommonErrorResponse>) => {
- if (extractStatusCode(error) == statusCode) {
- return errorHandler(error);
- } else {
- throw error;
- }
- };
-}
-
-export function convertToIfStatusCodeIs<NewError>(
- statusCode: number,
- newErrorType: {
- new (innerError: AxiosError): NewError;
- }
-): (error: AxiosError<CommonErrorResponse>) => never {
- return catchIfStatusCodeIs(statusCode, (error) => {
- throw new newErrorType(error);
- });
-}
-
-export function catchIfErrorCodeIs<
- TResult,
- TErrorHandlerResult extends TResult | PromiseLike<TResult> | null | undefined
->(
- errorCode: number,
- errorHandler: (error: AxiosError<CommonErrorResponse>) => TErrorHandlerResult
-): (error: AxiosError<CommonErrorResponse>) => TErrorHandlerResult {
- return (error: AxiosError<CommonErrorResponse>) => {
- if (extractErrorCode(error) == errorCode) {
- return errorHandler(error);
- } else {
- throw error;
- }
- };
-}
-export function convertToIfErrorCodeIs<NewError>(
- errorCode: number,
- newErrorType: {
- new (innerError: AxiosError): NewError;
- }
-): (error: AxiosError<CommonErrorResponse>) => never {
- return catchIfErrorCodeIs(errorCode, (error) => {
- throw new newErrorType(error);
- });
-}
-
-export function convertToNetworkError(
- error: AxiosError<CommonErrorResponse>
-): never {
- if (error.isAxiosError && error.response == null) {
- throw new HttpNetworkError(error);
- } else {
- throw error;
- }
-}
-
-export function convertToForbiddenError(
- error: AxiosError<CommonErrorResponse>
-): never {
- if (
- error.isAxiosError &&
- error.response != null &&
- (error.response.status == 401 || error.response.status == 403)
- ) {
- throw new HttpForbiddenError(error);
- } else {
- throw error;
- }
-}
-
-export function convertToNotModified(
- error: AxiosError<CommonErrorResponse>
-): NotModified {
- if (
- error.isAxiosError &&
- error.response != null &&
- error.response.status == 304
- ) {
- return new NotModified();
- } else {
- throw error;
- }
-}
-
-export function convertToBlobWithEtag(res: AxiosResponse<Blob>): BlobWithEtag {
- return {
- data: res.data,
- etag: (res.headers as Record<'etag', string>)['etag'],
- };
-}
+import { AxiosError, AxiosResponse } from "axios"; + +export const apiBaseUrl = "/api"; + +export function base64(blob: Blob): Promise<string> { + return new Promise<string>((resolve) => { + const reader = new FileReader(); + reader.onload = function () { + resolve((reader.result as string).replace(/^data:.+;base64,/, "")); + }; + reader.readAsDataURL(blob); + }); +} + +export function extractStatusCode(error: AxiosError): number | null { + if (error.isAxiosError) { + const code = error?.response?.status; + if (typeof code === "number") { + return code; + } + } + return null; +} + +export interface CommonErrorResponse { + code: number; + message: string; +} + +export function extractErrorCode( + error: AxiosError<CommonErrorResponse> +): number | null { + if (error.isAxiosError) { + const code = error.response?.data?.code; + if (typeof code === "number") { + return code; + } + } + return null; +} + +export class HttpNetworkError extends Error { + constructor(public innerError?: AxiosError) { + super(); + } +} + +export class HttpForbiddenError extends Error { + constructor(public innerError?: AxiosError) { + super(); + } +} + +export class NotModified {} + +export interface BlobWithEtag { + data: Blob; + etag: string; +} + +export function extractResponseData<T>(res: AxiosResponse<T>): T { + return res.data; +} + +export function catchIfStatusCodeIs< + TResult, + TErrorHandlerResult extends TResult | PromiseLike<TResult> | null | undefined +>( + statusCode: number, + errorHandler: (error: AxiosError<CommonErrorResponse>) => TErrorHandlerResult +): (error: AxiosError<CommonErrorResponse>) => TErrorHandlerResult { + return (error: AxiosError<CommonErrorResponse>) => { + if (extractStatusCode(error) == statusCode) { + return errorHandler(error); + } else { + throw error; + } + }; +} + +export function convertToIfStatusCodeIs<NewError>( + statusCode: number, + newErrorType: { + new (innerError: AxiosError): NewError; + } +): (error: AxiosError<CommonErrorResponse>) => never { + return catchIfStatusCodeIs(statusCode, (error) => { + throw new newErrorType(error); + }); +} + +export function catchIfErrorCodeIs< + TResult, + TErrorHandlerResult extends TResult | PromiseLike<TResult> | null | undefined +>( + errorCode: number, + errorHandler: (error: AxiosError<CommonErrorResponse>) => TErrorHandlerResult +): (error: AxiosError<CommonErrorResponse>) => TErrorHandlerResult { + return (error: AxiosError<CommonErrorResponse>) => { + if (extractErrorCode(error) == errorCode) { + return errorHandler(error); + } else { + throw error; + } + }; +} +export function convertToIfErrorCodeIs<NewError>( + errorCode: number, + newErrorType: { + new (innerError: AxiosError): NewError; + } +): (error: AxiosError<CommonErrorResponse>) => never { + return catchIfErrorCodeIs(errorCode, (error) => { + throw new newErrorType(error); + }); +} + +export function convertToNetworkError( + error: AxiosError<CommonErrorResponse> +): never { + if (error.isAxiosError && error.response == null) { + throw new HttpNetworkError(error); + } else { + throw error; + } +} + +export function convertToForbiddenError( + error: AxiosError<CommonErrorResponse> +): never { + if ( + error.isAxiosError && + error.response != null && + (error.response.status == 401 || error.response.status == 403) + ) { + throw new HttpForbiddenError(error); + } else { + throw error; + } +} + +export function convertToNotModified( + error: AxiosError<CommonErrorResponse> +): NotModified { + if ( + error.isAxiosError && + error.response != null && + error.response.status == 304 + ) { + return new NotModified(); + } else { + throw error; + } +} + +export function convertToBlobWithEtag(res: AxiosResponse<Blob>): BlobWithEtag { + return { + data: res.data, + etag: (res.headers as Record<"etag", string>)["etag"], + }; +} diff --git a/Timeline/ClientApp/src/app/http/mock/common.ts b/Timeline/ClientApp/src/app/http/mock/common.ts index 3dce8117..787d81bd 100644 --- a/Timeline/ClientApp/src/app/http/mock/common.ts +++ b/Timeline/ClientApp/src/app/http/mock/common.ts @@ -1,78 +1,78 @@ -import localforage from 'localforage';
-import { SHA1 } from 'crypto-js';
-
-import { HttpNetworkError } from '../common';
-
-export const mockStorage = localforage.createInstance({
- name: 'mock-backend',
- description: 'Database for mock back end.',
- driver: localforage.INDEXEDDB,
-});
-
-export async function sha1(data: Blob): Promise<string> {
- const s = await new Promise<string>((resolve) => {
- const fileReader = new FileReader();
- fileReader.readAsBinaryString(data);
- fileReader.onload = () => {
- resolve(fileReader.result as string);
- };
- });
-
- return SHA1(s).toString();
-}
-
-const disableNetworkKey = 'mockServer.disableNetwork';
-const networkLatencyKey = 'mockServer.networkLatency';
-
-let disableNetwork: boolean =
- localStorage.getItem(disableNetworkKey) === 'true' ? true : false;
-
-const savedNetworkLatency = localStorage.getItem(networkLatencyKey);
-
-let networkLatency: number | null =
- savedNetworkLatency != null ? Number(savedNetworkLatency) : null;
-
-Object.defineProperty(window, 'disableNetwork', {
- get: () => disableNetwork,
- set: (value) => {
- if (value) {
- disableNetwork = true;
- localStorage.setItem(disableNetworkKey, 'true');
- } else {
- disableNetwork = false;
- localStorage.setItem(disableNetworkKey, 'false');
- }
- },
-});
-
-Object.defineProperty(window, 'networkLatency', {
- get: () => networkLatency,
- set: (value) => {
- if (typeof value === 'number') {
- networkLatency = value;
- localStorage.setItem(networkLatencyKey, value.toString());
- } else if (value == null) {
- networkLatency = null;
- localStorage.removeItem(networkLatencyKey);
- }
- },
-});
-
-export async function mockPrepare(key: string): Promise<void> {
- console.log(`Recieve request: ${key}`);
-
- if (disableNetwork) {
- console.warn('Network is disabled for mock server.');
- throw new HttpNetworkError();
- }
- if (networkLatency != null) {
- await new Promise((resolve) => {
- window.setTimeout(() => {
- resolve();
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- }, networkLatency! * 1000);
- });
- }
-
- await Promise.resolve();
-}
+import localforage from "localforage"; +import { SHA1 } from "crypto-js"; + +import { HttpNetworkError } from "../common"; + +export const mockStorage = localforage.createInstance({ + name: "mock-backend", + description: "Database for mock back end.", + driver: localforage.INDEXEDDB, +}); + +export async function sha1(data: Blob): Promise<string> { + const s = await new Promise<string>((resolve) => { + const fileReader = new FileReader(); + fileReader.readAsBinaryString(data); + fileReader.onload = () => { + resolve(fileReader.result as string); + }; + }); + + return SHA1(s).toString(); +} + +const disableNetworkKey = "mockServer.disableNetwork"; +const networkLatencyKey = "mockServer.networkLatency"; + +let disableNetwork: boolean = + localStorage.getItem(disableNetworkKey) === "true" ? true : false; + +const savedNetworkLatency = localStorage.getItem(networkLatencyKey); + +let networkLatency: number | null = + savedNetworkLatency != null ? Number(savedNetworkLatency) : null; + +Object.defineProperty(window, "disableNetwork", { + get: () => disableNetwork, + set: (value) => { + if (value) { + disableNetwork = true; + localStorage.setItem(disableNetworkKey, "true"); + } else { + disableNetwork = false; + localStorage.setItem(disableNetworkKey, "false"); + } + }, +}); + +Object.defineProperty(window, "networkLatency", { + get: () => networkLatency, + set: (value) => { + if (typeof value === "number") { + networkLatency = value; + localStorage.setItem(networkLatencyKey, value.toString()); + } else if (value == null) { + networkLatency = null; + localStorage.removeItem(networkLatencyKey); + } + }, +}); + +export async function mockPrepare(key: string): Promise<void> { + console.log(`Recieve request: ${key}`); + + if (disableNetwork) { + console.warn("Network is disabled for mock server."); + throw new HttpNetworkError(); + } + if (networkLatency != null) { + await new Promise((resolve) => { + window.setTimeout(() => { + resolve(); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + }, networkLatency! * 1000); + }); + } + + await Promise.resolve(); +} diff --git a/Timeline/ClientApp/src/app/http/mock/install.ts b/Timeline/ClientApp/src/app/http/mock/install.ts index 66174d41..17b7cc13 100644 --- a/Timeline/ClientApp/src/app/http/mock/install.ts +++ b/Timeline/ClientApp/src/app/http/mock/install.ts @@ -1,11 +1,11 @@ -import { setHttpTokenClient } from '../token';
-import { setHttpUserClient } from '../user';
-import { setHttpTimelineClient } from '../timeline';
-
-import { MockHttpTokenClient } from './token';
-import { MockHttpUserClient } from './user';
-import { MockHttpTimelineClient } from './timeline';
-
-setHttpTokenClient(new MockHttpTokenClient());
-setHttpUserClient(new MockHttpUserClient());
-setHttpTimelineClient(new MockHttpTimelineClient());
+import { setHttpTokenClient } from "../token"; +import { setHttpUserClient } from "../user"; +import { setHttpTimelineClient } from "../timeline"; + +import { MockHttpTokenClient } from "./token"; +import { MockHttpUserClient } from "./user"; +import { MockHttpTimelineClient } from "./timeline"; + +setHttpTokenClient(new MockHttpTokenClient()); +setHttpUserClient(new MockHttpUserClient()); +setHttpTimelineClient(new MockHttpTimelineClient()); diff --git a/Timeline/ClientApp/src/app/http/mock/timeline.ts b/Timeline/ClientApp/src/app/http/mock/timeline.ts index 9434f666..0330b303 100644 --- a/Timeline/ClientApp/src/app/http/mock/timeline.ts +++ b/Timeline/ClientApp/src/app/http/mock/timeline.ts @@ -1,658 +1,658 @@ -import { random, without, range } from 'lodash';
-
-import { BlobWithEtag, NotModified } from '../common';
-import {
- IHttpTimelineClient,
- HttpTimelineInfo,
- TimelineVisibility,
- HttpTimelineListQuery,
- HttpTimelineNotExistError,
- HttpTimelinePostRequest,
- HttpTimelineNameConflictError,
- HttpTimelinePatchRequest,
- HttpTimelinePostInfo,
- HttpTimelinePostContent,
- HttpTimelinePostPostRequest,
- HttpTimelinePostNotExistError,
- HttpTimelineGenericPostInfo,
-} from '../timeline';
-import { HttpUser } from '../user';
-
-import { mockStorage, sha1, mockPrepare } from './common';
-import { getUser, MockUserNotExistError, checkToken } from './user';
-
-async function getTimelineNameList(): Promise<string[]> {
- return (await mockStorage.getItem<string[]>('timelines')) ?? [];
-}
-
-async function setTimelineNameList(newOne: string[]): Promise<void> {
- await mockStorage.setItem<string[]>('timelines', newOne);
-}
-
-type TimelinePropertyKey =
- | 'uniqueId'
- | 'lastModified'
- | 'owner'
- | 'description'
- | 'visibility'
- | 'members'
- | 'currentPostId';
-
-function getTimelinePropertyKey(
- name: string,
- property: TimelinePropertyKey
-): string {
- return `timeline.${name}.${property}`;
-}
-
-function getTimelinePropertyValue<T>(
- name: string,
- property: TimelinePropertyKey
-): Promise<T> {
- return mockStorage.getItem<T>(getTimelinePropertyKey(name, property));
-}
-
-function setTimelinePropertyValue<T>(
- name: string,
- property: TimelinePropertyKey,
- value: T
-): Promise<void> {
- return mockStorage
- .setItem<T>(getTimelinePropertyKey(name, property), value)
- .then();
-}
-
-function updateTimelineLastModified(name: string): Promise<void> {
- return setTimelinePropertyValue(
- name,
- 'lastModified',
- new Date().toISOString()
- );
-}
-
-interface HttpTimelineInfoEx extends HttpTimelineInfo {
- memberUsernames: string[];
-}
-
-function createUniqueId(): string {
- const s = 'abcdefghijklmnopqrstuvwxz0123456789';
- let result = '';
- for (let i = 0; i < 16; i++) {
- result += s[random(0, s.length - 1)];
- }
- return result;
-}
-
-class MockTimelineNotExistError extends Error {
- constructor() {
- super('Timeline not exist.');
- }
-}
-
-class MockTimelineAlreadyExistError extends Error {
- constructor() {
- super('Timeline already exist.');
- }
-}
-
-async function getTimelineInfo(name: string): Promise<HttpTimelineInfoEx> {
- let owner: HttpUser;
- if (name.startsWith('@')) {
- const ownerUsername = name.substr(1);
- owner = await getUser(ownerUsername);
- const optionalUniqueId = await getTimelinePropertyValue<string | null>(
- name,
- 'uniqueId'
- );
- if (optionalUniqueId == null) {
- await setTimelineNameList([...(await getTimelineNameList()), name]);
- await setTimelinePropertyValue(name, 'uniqueId', createUniqueId());
- await updateTimelineLastModified(name);
- }
- } else {
- const optionalOwnerUsername = await getTimelinePropertyValue<string | null>(
- name,
- 'owner'
- );
- if (optionalOwnerUsername == null) {
- throw new MockTimelineNotExistError();
- } else {
- owner = await getUser(optionalOwnerUsername);
- }
- }
-
- const memberUsernames =
- (await getTimelinePropertyValue<string[] | null>(name, 'members')) ?? [];
- const members = await Promise.all(
- memberUsernames.map(async (username) => {
- return await getUser(username);
- })
- );
-
- return {
- name,
- uniqueId: await getTimelinePropertyValue<string>(name, 'uniqueId'),
- owner,
- description:
- (await getTimelinePropertyValue<string | null>(name, 'description')) ??
- '',
- visibility:
- (await getTimelinePropertyValue<TimelineVisibility | null>(
- name,
- 'visibility'
- )) ?? 'Register',
- lastModified: new Date(
- await getTimelinePropertyValue<string>(name, 'lastModified')
- ),
- members,
- memberUsernames,
- };
-}
-
-async function createTimeline(name: string, owner: string): Promise<void> {
- const optionalOwnerUsername = await getTimelinePropertyValue<string | null>(
- name,
- 'owner'
- );
- if (optionalOwnerUsername != null) {
- throw new MockTimelineAlreadyExistError();
- }
-
- await setTimelineNameList([...(await getTimelineNameList()), name]);
- await setTimelinePropertyValue(name, 'uniqueId', createUniqueId());
- await setTimelinePropertyValue(name, 'owner', owner);
- await updateTimelineLastModified(name);
-}
-
-type TimelinePostPropertyKey =
- | 'type'
- | 'data'
- | 'etag'
- | 'author'
- | 'time'
- | 'lastUpdated';
-
-function getTimelinePostPropertyKey(
- timelineName: string,
- id: number,
- propertyKey: TimelinePostPropertyKey
-): string {
- return `timeline.${timelineName}.posts.${id}.${propertyKey}`;
-}
-
-function getTimelinePostPropertyValue<T>(
- timelineName: string,
- id: number,
- propertyKey: TimelinePostPropertyKey
-): Promise<T> {
- return mockStorage.getItem<T>(
- getTimelinePostPropertyKey(timelineName, id, propertyKey)
- );
-}
-
-function setTimelinePostPropertyValue<T>(
- timelineName: string,
- id: number,
- propertyKey: TimelinePostPropertyKey,
- value: T
-): Promise<T> {
- return mockStorage.setItem(
- getTimelinePostPropertyKey(timelineName, id, propertyKey),
- value
- );
-}
-
-function removeTimelinePostProperty(
- timelineName: string,
- id: number,
- propertyKey: TimelinePostPropertyKey
-): Promise<void> {
- return mockStorage.removeItem(
- getTimelinePostPropertyKey(timelineName, id, propertyKey)
- );
-}
-
-async function getTimelinePostInfo(
- timelineName: string,
- id: number
-): Promise<HttpTimelineGenericPostInfo> {
- const currentPostId = await getTimelinePropertyValue<number | null>(
- timelineName,
- 'currentPostId'
- );
- if (currentPostId == null || id > currentPostId) {
- throw new HttpTimelinePostNotExistError();
- }
-
- const type = await getTimelinePostPropertyValue<string | null>(
- timelineName,
- id,
- 'type'
- );
-
- if (type == null) {
- return {
- id,
- author: await getUser(
- await getTimelinePostPropertyValue<string>(timelineName, id, 'author')
- ),
- time: new Date(
- await getTimelinePostPropertyValue<string>(timelineName, id, 'time')
- ),
- lastUpdated: new Date(
- await getTimelinePostPropertyValue<string>(
- timelineName,
- id,
- 'lastUpdated'
- )
- ),
- deleted: true,
- };
- } else {
- let content: HttpTimelinePostContent;
- if (type === 'text') {
- content = {
- type: 'text',
- text: await getTimelinePostPropertyValue(timelineName, id, 'data'),
- };
- } else {
- content = {
- type: 'image',
- };
- }
-
- return {
- id,
- author: await getUser(
- await getTimelinePostPropertyValue<string>(timelineName, id, 'author')
- ),
- time: new Date(
- await getTimelinePostPropertyValue<string>(timelineName, id, 'time')
- ),
- lastUpdated: new Date(
- await getTimelinePostPropertyValue<string>(
- timelineName,
- id,
- 'lastUpdated'
- )
- ),
- content,
- deleted: false,
- };
- }
-}
-
-export class MockHttpTimelineClient implements IHttpTimelineClient {
- async listTimeline(
- query: HttpTimelineListQuery
- ): Promise<HttpTimelineInfo[]> {
- await mockPrepare('timeline.list');
- return (
- await Promise.all(
- (await getTimelineNameList()).map((name) => getTimelineInfo(name))
- )
- ).filter((timeline) => {
- if (
- query.visibility != null &&
- query.visibility !== timeline.visibility
- ) {
- return false;
- }
- if (query.relate != null) {
- if (query.relateType === 'own') {
- if (timeline.owner.username !== query.relate) {
- return false;
- }
- } else if (query.relateType === 'join') {
- if (!timeline.memberUsernames.includes(query.relate)) {
- return false;
- }
- } else if (
- timeline.owner.username !== query.relate &&
- !timeline.memberUsernames.includes(query.relate)
- ) {
- return false;
- }
- }
- return true;
- });
- }
-
- getTimeline(timelineName: string): Promise<HttpTimelineInfo>;
- getTimeline(
- timelineName: string,
- query: {
- checkUniqueId?: string;
- }
- ): Promise<HttpTimelineInfo>;
- getTimeline(
- timelineName: string,
- query: {
- checkUniqueId?: string;
- ifModifiedSince: Date;
- }
- ): Promise<HttpTimelineInfo | NotModified>;
- async getTimeline(
- timelineName: string,
- query?: {
- checkUniqueId?: string;
- ifModifiedSince?: Date;
- }
- ): Promise<HttpTimelineInfo | NotModified> {
- await mockPrepare('timeline.get');
- try {
- const timeline = await getTimelineInfo(timelineName);
- if (query != null && query.ifModifiedSince != null) {
- if (timeline.lastModified >= query.ifModifiedSince) {
- return timeline;
- } else {
- if (
- query.checkUniqueId != null &&
- timeline.uniqueId != query.checkUniqueId
- ) {
- return timeline;
- } else {
- return new NotModified();
- }
- }
- }
-
- return timeline;
- } catch (e) {
- if (
- e instanceof MockTimelineNotExistError ||
- e instanceof MockUserNotExistError
- ) {
- throw new HttpTimelineNotExistError();
- }
- throw e;
- }
- }
-
- async postTimeline(
- req: HttpTimelinePostRequest,
- token: string
- ): Promise<HttpTimelineInfo> {
- await mockPrepare('timeline.post');
- const user = checkToken(token);
- try {
- await createTimeline(req.name, user);
- } catch (e) {
- if (e instanceof MockTimelineAlreadyExistError) {
- throw new HttpTimelineNameConflictError();
- }
- throw e;
- }
- return await getTimelineInfo(req.name);
- }
-
- async patchTimeline(
- timelineName: string,
- req: HttpTimelinePatchRequest,
- _token: string
- ): Promise<HttpTimelineInfo> {
- await mockPrepare('timeline.patch');
- let modified = false;
- if (req.description != null) {
- modified = true;
- await setTimelinePropertyValue(
- timelineName,
- 'description',
- req.description
- );
- }
- if (req.visibility != null) {
- modified = true;
- await setTimelinePropertyValue(
- timelineName,
- 'visibility',
- req.visibility
- );
- }
- if (modified) {
- await updateTimelineLastModified(timelineName);
- }
- return await getTimelineInfo(timelineName);
- }
-
- async deleteTimeline(timelineName: string, _token: string): Promise<void> {
- await mockPrepare('timeline.delete');
- await setTimelineNameList(
- without(await getTimelineNameList(), timelineName)
- );
- await mockStorage.removeItem(
- getTimelinePropertyKey(timelineName, 'uniqueId')
- );
-
- // TODO: remove other things
- }
-
- async memberPut(
- timelineName: string,
- username: string,
- _token: string
- ): Promise<void> {
- await mockPrepare('timeline.member.put');
- const oldMembers =
- (await getTimelinePropertyValue<string[] | null>(
- timelineName,
- 'members'
- )) ?? [];
- if (!oldMembers.includes(username)) {
- await setTimelinePropertyValue(timelineName, 'members', [
- ...oldMembers,
- username,
- ]);
- await updateTimelineLastModified(timelineName);
- }
- }
-
- async memberDelete(
- timelineName: string,
- username: string,
- _token: string
- ): Promise<void> {
- await mockPrepare('timeline.member.delete');
- const oldMembers =
- (await getTimelinePropertyValue<string[] | null>(
- timelineName,
- 'members'
- )) ?? [];
- if (oldMembers.includes(username)) {
- await setTimelinePropertyValue(
- timelineName,
- 'members',
- without(oldMembers, username)
- );
- await updateTimelineLastModified(timelineName);
- }
- }
-
- listPost(
- timelineName: string,
- token?: string
- ): Promise<HttpTimelinePostInfo[]>;
- listPost(
- timelineName: string,
- token: string | undefined,
- query: {
- modifiedSince?: Date;
- includeDeleted?: false;
- }
- ): Promise<HttpTimelinePostInfo[]>;
- listPost(
- timelineName: string,
- token: string | undefined,
- query: {
- modifiedSince?: Date;
- includeDeleted: true;
- }
- ): Promise<HttpTimelineGenericPostInfo[]>;
- async listPost(
- timelineName: string,
- _token?: string,
- query?: {
- modifiedSince?: Date;
- includeDeleted?: boolean;
- }
- ): Promise<HttpTimelineGenericPostInfo[]> {
- await mockPrepare('timeline.post.list');
- // TODO: Permission check.
-
- const currentPostId = await getTimelinePropertyValue<number | null>(
- timelineName,
- 'currentPostId'
- );
-
- return (
- await Promise.all(
- range(1, currentPostId == null ? 1 : currentPostId + 1).map(
- async (id) => {
- return await getTimelinePostInfo(timelineName, id);
- }
- )
- )
- )
- .filter((post) => {
- if (query?.includeDeleted !== true && post.deleted) {
- return false;
- }
- return true;
- })
- .filter((post) => {
- if (query?.modifiedSince != null) {
- return post.lastUpdated >= query.modifiedSince;
- }
- return true;
- });
- }
-
- getPostData(
- timelineName: string,
- postId: number,
- token: string
- ): Promise<BlobWithEtag>;
- async getPostData(
- timelineName: string,
- postId: number,
- _token?: string,
- etag?: string
- ): Promise<BlobWithEtag | NotModified> {
- await mockPrepare('timeline.post.data.get');
- // TODO: Permission check.
-
- const optionalSavedEtag = await getTimelinePostPropertyValue<string>(
- timelineName,
- postId,
- 'etag'
- );
-
- if (optionalSavedEtag == null) {
- const optionalType = await getTimelinePostPropertyValue<string>(
- timelineName,
- postId,
- 'type'
- );
-
- if (optionalType != null) {
- throw new Error('Post of this type has no data.');
- } else {
- throw new HttpTimelinePostNotExistError();
- }
- }
-
- if (etag === optionalSavedEtag) {
- return new NotModified();
- }
-
- return {
- data: await getTimelinePostPropertyValue<Blob>(
- timelineName,
- postId,
- 'data'
- ),
- etag: optionalSavedEtag,
- };
- }
-
- async postPost(
- timelineName: string,
- req: HttpTimelinePostPostRequest,
- token: string
- ): Promise<HttpTimelinePostInfo> {
- await mockPrepare('timeline.post.post');
- const user = checkToken(token);
-
- const savedId = await getTimelinePropertyValue<number | null>(
- timelineName,
- 'currentPostId'
- );
- const id = savedId ? savedId + 1 : 1;
- await setTimelinePropertyValue(timelineName, 'currentPostId', id);
-
- await setTimelinePostPropertyValue(timelineName, id, 'author', user);
-
- const currentTimeString = new Date().toISOString();
- await setTimelinePostPropertyValue(
- timelineName,
- id,
- 'lastUpdated',
- currentTimeString
- );
-
- await setTimelinePostPropertyValue(
- timelineName,
- id,
- 'time',
- req.time != null ? req.time.toISOString() : currentTimeString
- );
-
- const { content } = req;
- if (content.type === 'text') {
- await setTimelinePostPropertyValue(timelineName, id, 'type', 'text');
- await setTimelinePostPropertyValue(
- timelineName,
- id,
- 'data',
- content.text
- );
- } else {
- await setTimelinePostPropertyValue(timelineName, id, 'type', 'image');
- await setTimelinePostPropertyValue(
- timelineName,
- id,
- 'data',
- content.data
- );
- await setTimelinePostPropertyValue(
- timelineName,
- id,
- 'etag',
- await sha1(content.data)
- );
- }
-
- return (await getTimelinePostInfo(
- timelineName,
- id
- )) as HttpTimelinePostInfo;
- }
-
- async deletePost(
- timelineName: string,
- postId: number,
- _token: string
- ): Promise<void> {
- await mockPrepare('timeline.post.delete');
- // TODO: permission check
- await removeTimelinePostProperty(timelineName, postId, 'type');
- await removeTimelinePostProperty(timelineName, postId, 'data');
- await removeTimelinePostProperty(timelineName, postId, 'etag');
- await setTimelinePostPropertyValue(
- timelineName,
- postId,
- 'lastUpdated',
- new Date().toISOString()
- );
- }
-}
+import { random, without, range } from "lodash"; + +import { BlobWithEtag, NotModified } from "../common"; +import { + IHttpTimelineClient, + HttpTimelineInfo, + TimelineVisibility, + HttpTimelineListQuery, + HttpTimelineNotExistError, + HttpTimelinePostRequest, + HttpTimelineNameConflictError, + HttpTimelinePatchRequest, + HttpTimelinePostInfo, + HttpTimelinePostContent, + HttpTimelinePostPostRequest, + HttpTimelinePostNotExistError, + HttpTimelineGenericPostInfo, +} from "../timeline"; +import { HttpUser } from "../user"; + +import { mockStorage, sha1, mockPrepare } from "./common"; +import { getUser, MockUserNotExistError, checkToken } from "./user"; + +async function getTimelineNameList(): Promise<string[]> { + return (await mockStorage.getItem<string[]>("timelines")) ?? []; +} + +async function setTimelineNameList(newOne: string[]): Promise<void> { + await mockStorage.setItem<string[]>("timelines", newOne); +} + +type TimelinePropertyKey = + | "uniqueId" + | "lastModified" + | "owner" + | "description" + | "visibility" + | "members" + | "currentPostId"; + +function getTimelinePropertyKey( + name: string, + property: TimelinePropertyKey +): string { + return `timeline.${name}.${property}`; +} + +function getTimelinePropertyValue<T>( + name: string, + property: TimelinePropertyKey +): Promise<T> { + return mockStorage.getItem<T>(getTimelinePropertyKey(name, property)); +} + +function setTimelinePropertyValue<T>( + name: string, + property: TimelinePropertyKey, + value: T +): Promise<void> { + return mockStorage + .setItem<T>(getTimelinePropertyKey(name, property), value) + .then(); +} + +function updateTimelineLastModified(name: string): Promise<void> { + return setTimelinePropertyValue( + name, + "lastModified", + new Date().toISOString() + ); +} + +interface HttpTimelineInfoEx extends HttpTimelineInfo { + memberUsernames: string[]; +} + +function createUniqueId(): string { + const s = "abcdefghijklmnopqrstuvwxz0123456789"; + let result = ""; + for (let i = 0; i < 16; i++) { + result += s[random(0, s.length - 1)]; + } + return result; +} + +class MockTimelineNotExistError extends Error { + constructor() { + super("Timeline not exist."); + } +} + +class MockTimelineAlreadyExistError extends Error { + constructor() { + super("Timeline already exist."); + } +} + +async function getTimelineInfo(name: string): Promise<HttpTimelineInfoEx> { + let owner: HttpUser; + if (name.startsWith("@")) { + const ownerUsername = name.substr(1); + owner = await getUser(ownerUsername); + const optionalUniqueId = await getTimelinePropertyValue<string | null>( + name, + "uniqueId" + ); + if (optionalUniqueId == null) { + await setTimelineNameList([...(await getTimelineNameList()), name]); + await setTimelinePropertyValue(name, "uniqueId", createUniqueId()); + await updateTimelineLastModified(name); + } + } else { + const optionalOwnerUsername = await getTimelinePropertyValue<string | null>( + name, + "owner" + ); + if (optionalOwnerUsername == null) { + throw new MockTimelineNotExistError(); + } else { + owner = await getUser(optionalOwnerUsername); + } + } + + const memberUsernames = + (await getTimelinePropertyValue<string[] | null>(name, "members")) ?? []; + const members = await Promise.all( + memberUsernames.map(async (username) => { + return await getUser(username); + }) + ); + + return { + name, + uniqueId: await getTimelinePropertyValue<string>(name, "uniqueId"), + owner, + description: + (await getTimelinePropertyValue<string | null>(name, "description")) ?? + "", + visibility: + (await getTimelinePropertyValue<TimelineVisibility | null>( + name, + "visibility" + )) ?? "Register", + lastModified: new Date( + await getTimelinePropertyValue<string>(name, "lastModified") + ), + members, + memberUsernames, + }; +} + +async function createTimeline(name: string, owner: string): Promise<void> { + const optionalOwnerUsername = await getTimelinePropertyValue<string | null>( + name, + "owner" + ); + if (optionalOwnerUsername != null) { + throw new MockTimelineAlreadyExistError(); + } + + await setTimelineNameList([...(await getTimelineNameList()), name]); + await setTimelinePropertyValue(name, "uniqueId", createUniqueId()); + await setTimelinePropertyValue(name, "owner", owner); + await updateTimelineLastModified(name); +} + +type TimelinePostPropertyKey = + | "type" + | "data" + | "etag" + | "author" + | "time" + | "lastUpdated"; + +function getTimelinePostPropertyKey( + timelineName: string, + id: number, + propertyKey: TimelinePostPropertyKey +): string { + return `timeline.${timelineName}.posts.${id}.${propertyKey}`; +} + +function getTimelinePostPropertyValue<T>( + timelineName: string, + id: number, + propertyKey: TimelinePostPropertyKey +): Promise<T> { + return mockStorage.getItem<T>( + getTimelinePostPropertyKey(timelineName, id, propertyKey) + ); +} + +function setTimelinePostPropertyValue<T>( + timelineName: string, + id: number, + propertyKey: TimelinePostPropertyKey, + value: T +): Promise<T> { + return mockStorage.setItem( + getTimelinePostPropertyKey(timelineName, id, propertyKey), + value + ); +} + +function removeTimelinePostProperty( + timelineName: string, + id: number, + propertyKey: TimelinePostPropertyKey +): Promise<void> { + return mockStorage.removeItem( + getTimelinePostPropertyKey(timelineName, id, propertyKey) + ); +} + +async function getTimelinePostInfo( + timelineName: string, + id: number +): Promise<HttpTimelineGenericPostInfo> { + const currentPostId = await getTimelinePropertyValue<number | null>( + timelineName, + "currentPostId" + ); + if (currentPostId == null || id > currentPostId) { + throw new HttpTimelinePostNotExistError(); + } + + const type = await getTimelinePostPropertyValue<string | null>( + timelineName, + id, + "type" + ); + + if (type == null) { + return { + id, + author: await getUser( + await getTimelinePostPropertyValue<string>(timelineName, id, "author") + ), + time: new Date( + await getTimelinePostPropertyValue<string>(timelineName, id, "time") + ), + lastUpdated: new Date( + await getTimelinePostPropertyValue<string>( + timelineName, + id, + "lastUpdated" + ) + ), + deleted: true, + }; + } else { + let content: HttpTimelinePostContent; + if (type === "text") { + content = { + type: "text", + text: await getTimelinePostPropertyValue(timelineName, id, "data"), + }; + } else { + content = { + type: "image", + }; + } + + return { + id, + author: await getUser( + await getTimelinePostPropertyValue<string>(timelineName, id, "author") + ), + time: new Date( + await getTimelinePostPropertyValue<string>(timelineName, id, "time") + ), + lastUpdated: new Date( + await getTimelinePostPropertyValue<string>( + timelineName, + id, + "lastUpdated" + ) + ), + content, + deleted: false, + }; + } +} + +export class MockHttpTimelineClient implements IHttpTimelineClient { + async listTimeline( + query: HttpTimelineListQuery + ): Promise<HttpTimelineInfo[]> { + await mockPrepare("timeline.list"); + return ( + await Promise.all( + (await getTimelineNameList()).map((name) => getTimelineInfo(name)) + ) + ).filter((timeline) => { + if ( + query.visibility != null && + query.visibility !== timeline.visibility + ) { + return false; + } + if (query.relate != null) { + if (query.relateType === "own") { + if (timeline.owner.username !== query.relate) { + return false; + } + } else if (query.relateType === "join") { + if (!timeline.memberUsernames.includes(query.relate)) { + return false; + } + } else if ( + timeline.owner.username !== query.relate && + !timeline.memberUsernames.includes(query.relate) + ) { + return false; + } + } + return true; + }); + } + + getTimeline(timelineName: string): Promise<HttpTimelineInfo>; + getTimeline( + timelineName: string, + query: { + checkUniqueId?: string; + } + ): Promise<HttpTimelineInfo>; + getTimeline( + timelineName: string, + query: { + checkUniqueId?: string; + ifModifiedSince: Date; + } + ): Promise<HttpTimelineInfo | NotModified>; + async getTimeline( + timelineName: string, + query?: { + checkUniqueId?: string; + ifModifiedSince?: Date; + } + ): Promise<HttpTimelineInfo | NotModified> { + await mockPrepare("timeline.get"); + try { + const timeline = await getTimelineInfo(timelineName); + if (query != null && query.ifModifiedSince != null) { + if (timeline.lastModified >= query.ifModifiedSince) { + return timeline; + } else { + if ( + query.checkUniqueId != null && + timeline.uniqueId != query.checkUniqueId + ) { + return timeline; + } else { + return new NotModified(); + } + } + } + + return timeline; + } catch (e) { + if ( + e instanceof MockTimelineNotExistError || + e instanceof MockUserNotExistError + ) { + throw new HttpTimelineNotExistError(); + } + throw e; + } + } + + async postTimeline( + req: HttpTimelinePostRequest, + token: string + ): Promise<HttpTimelineInfo> { + await mockPrepare("timeline.post"); + const user = checkToken(token); + try { + await createTimeline(req.name, user); + } catch (e) { + if (e instanceof MockTimelineAlreadyExistError) { + throw new HttpTimelineNameConflictError(); + } + throw e; + } + return await getTimelineInfo(req.name); + } + + async patchTimeline( + timelineName: string, + req: HttpTimelinePatchRequest, + _token: string + ): Promise<HttpTimelineInfo> { + await mockPrepare("timeline.patch"); + let modified = false; + if (req.description != null) { + modified = true; + await setTimelinePropertyValue( + timelineName, + "description", + req.description + ); + } + if (req.visibility != null) { + modified = true; + await setTimelinePropertyValue( + timelineName, + "visibility", + req.visibility + ); + } + if (modified) { + await updateTimelineLastModified(timelineName); + } + return await getTimelineInfo(timelineName); + } + + async deleteTimeline(timelineName: string, _token: string): Promise<void> { + await mockPrepare("timeline.delete"); + await setTimelineNameList( + without(await getTimelineNameList(), timelineName) + ); + await mockStorage.removeItem( + getTimelinePropertyKey(timelineName, "uniqueId") + ); + + // TODO: remove other things + } + + async memberPut( + timelineName: string, + username: string, + _token: string + ): Promise<void> { + await mockPrepare("timeline.member.put"); + const oldMembers = + (await getTimelinePropertyValue<string[] | null>( + timelineName, + "members" + )) ?? []; + if (!oldMembers.includes(username)) { + await setTimelinePropertyValue(timelineName, "members", [ + ...oldMembers, + username, + ]); + await updateTimelineLastModified(timelineName); + } + } + + async memberDelete( + timelineName: string, + username: string, + _token: string + ): Promise<void> { + await mockPrepare("timeline.member.delete"); + const oldMembers = + (await getTimelinePropertyValue<string[] | null>( + timelineName, + "members" + )) ?? []; + if (oldMembers.includes(username)) { + await setTimelinePropertyValue( + timelineName, + "members", + without(oldMembers, username) + ); + await updateTimelineLastModified(timelineName); + } + } + + listPost( + timelineName: string, + token?: string + ): Promise<HttpTimelinePostInfo[]>; + listPost( + timelineName: string, + token: string | undefined, + query: { + modifiedSince?: Date; + includeDeleted?: false; + } + ): Promise<HttpTimelinePostInfo[]>; + listPost( + timelineName: string, + token: string | undefined, + query: { + modifiedSince?: Date; + includeDeleted: true; + } + ): Promise<HttpTimelineGenericPostInfo[]>; + async listPost( + timelineName: string, + _token?: string, + query?: { + modifiedSince?: Date; + includeDeleted?: boolean; + } + ): Promise<HttpTimelineGenericPostInfo[]> { + await mockPrepare("timeline.post.list"); + // TODO: Permission check. + + const currentPostId = await getTimelinePropertyValue<number | null>( + timelineName, + "currentPostId" + ); + + return ( + await Promise.all( + range(1, currentPostId == null ? 1 : currentPostId + 1).map( + async (id) => { + return await getTimelinePostInfo(timelineName, id); + } + ) + ) + ) + .filter((post) => { + if (query?.includeDeleted !== true && post.deleted) { + return false; + } + return true; + }) + .filter((post) => { + if (query?.modifiedSince != null) { + return post.lastUpdated >= query.modifiedSince; + } + return true; + }); + } + + getPostData( + timelineName: string, + postId: number, + token: string + ): Promise<BlobWithEtag>; + async getPostData( + timelineName: string, + postId: number, + _token?: string, + etag?: string + ): Promise<BlobWithEtag | NotModified> { + await mockPrepare("timeline.post.data.get"); + // TODO: Permission check. + + const optionalSavedEtag = await getTimelinePostPropertyValue<string>( + timelineName, + postId, + "etag" + ); + + if (optionalSavedEtag == null) { + const optionalType = await getTimelinePostPropertyValue<string>( + timelineName, + postId, + "type" + ); + + if (optionalType != null) { + throw new Error("Post of this type has no data."); + } else { + throw new HttpTimelinePostNotExistError(); + } + } + + if (etag === optionalSavedEtag) { + return new NotModified(); + } + + return { + data: await getTimelinePostPropertyValue<Blob>( + timelineName, + postId, + "data" + ), + etag: optionalSavedEtag, + }; + } + + async postPost( + timelineName: string, + req: HttpTimelinePostPostRequest, + token: string + ): Promise<HttpTimelinePostInfo> { + await mockPrepare("timeline.post.post"); + const user = checkToken(token); + + const savedId = await getTimelinePropertyValue<number | null>( + timelineName, + "currentPostId" + ); + const id = savedId ? savedId + 1 : 1; + await setTimelinePropertyValue(timelineName, "currentPostId", id); + + await setTimelinePostPropertyValue(timelineName, id, "author", user); + + const currentTimeString = new Date().toISOString(); + await setTimelinePostPropertyValue( + timelineName, + id, + "lastUpdated", + currentTimeString + ); + + await setTimelinePostPropertyValue( + timelineName, + id, + "time", + req.time != null ? req.time.toISOString() : currentTimeString + ); + + const { content } = req; + if (content.type === "text") { + await setTimelinePostPropertyValue(timelineName, id, "type", "text"); + await setTimelinePostPropertyValue( + timelineName, + id, + "data", + content.text + ); + } else { + await setTimelinePostPropertyValue(timelineName, id, "type", "image"); + await setTimelinePostPropertyValue( + timelineName, + id, + "data", + content.data + ); + await setTimelinePostPropertyValue( + timelineName, + id, + "etag", + await sha1(content.data) + ); + } + + return (await getTimelinePostInfo( + timelineName, + id + )) as HttpTimelinePostInfo; + } + + async deletePost( + timelineName: string, + postId: number, + _token: string + ): Promise<void> { + await mockPrepare("timeline.post.delete"); + // TODO: permission check + await removeTimelinePostProperty(timelineName, postId, "type"); + await removeTimelinePostProperty(timelineName, postId, "data"); + await removeTimelinePostProperty(timelineName, postId, "etag"); + await setTimelinePostPropertyValue( + timelineName, + postId, + "lastUpdated", + new Date().toISOString() + ); + } +} diff --git a/Timeline/ClientApp/src/app/http/mock/token.ts b/Timeline/ClientApp/src/app/http/mock/token.ts index 6929be2a..0a350894 100644 --- a/Timeline/ClientApp/src/app/http/mock/token.ts +++ b/Timeline/ClientApp/src/app/http/mock/token.ts @@ -1,53 +1,53 @@ -import { AxiosError } from 'axios';
-
-import {
- IHttpTokenClient,
- HttpCreateTokenRequest,
- HttpCreateTokenResponse,
- HttpVerifyTokenRequest,
- HttpVerifyTokenResponse,
-} from '../token';
-
-import { mockPrepare } from './common';
-import { getUser, MockUserNotExistError, checkToken } from './user';
-
-export class MockHttpTokenClient implements IHttpTokenClient {
- // TODO: Mock bad credentials error.
- async create(req: HttpCreateTokenRequest): Promise<HttpCreateTokenResponse> {
- await mockPrepare('token.create');
- try {
- const user = await getUser(req.username);
- return {
- user,
- token: `token-${req.username}`,
- };
- } catch (e) {
- if (e instanceof MockUserNotExistError) {
- throw {
- isAxiosError: true,
- response: {
- status: 400,
- },
- } as Partial<AxiosError>;
- }
- throw e;
- }
- }
-
- async verify(req: HttpVerifyTokenRequest): Promise<HttpVerifyTokenResponse> {
- await mockPrepare('token.verify');
- try {
- const user = await getUser(checkToken(req.token));
- return {
- user,
- };
- } catch (e) {
- throw {
- isAxiosError: true,
- response: {
- status: 400,
- },
- } as Partial<AxiosError>;
- }
- }
-}
+import { AxiosError } from "axios"; + +import { + IHttpTokenClient, + HttpCreateTokenRequest, + HttpCreateTokenResponse, + HttpVerifyTokenRequest, + HttpVerifyTokenResponse, +} from "../token"; + +import { mockPrepare } from "./common"; +import { getUser, MockUserNotExistError, checkToken } from "./user"; + +export class MockHttpTokenClient implements IHttpTokenClient { + // TODO: Mock bad credentials error. + async create(req: HttpCreateTokenRequest): Promise<HttpCreateTokenResponse> { + await mockPrepare("token.create"); + try { + const user = await getUser(req.username); + return { + user, + token: `token-${req.username}`, + }; + } catch (e) { + if (e instanceof MockUserNotExistError) { + throw { + isAxiosError: true, + response: { + status: 400, + }, + } as Partial<AxiosError>; + } + throw e; + } + } + + async verify(req: HttpVerifyTokenRequest): Promise<HttpVerifyTokenResponse> { + await mockPrepare("token.verify"); + try { + const user = await getUser(checkToken(req.token)); + return { + user, + }; + } catch (e) { + throw { + isAxiosError: true, + response: { + status: 400, + }, + } as Partial<AxiosError>; + } + } +} diff --git a/Timeline/ClientApp/src/app/http/mock/user.ts b/Timeline/ClientApp/src/app/http/mock/user.ts index 76a35f17..1ecd7365 100644 --- a/Timeline/ClientApp/src/app/http/mock/user.ts +++ b/Timeline/ClientApp/src/app/http/mock/user.ts @@ -1,140 +1,140 @@ -import axios from 'axios';
-
-import { BlobWithEtag, NotModified } from '../common';
-import {
- IHttpUserClient,
- HttpUser,
- HttpUserNotExistError,
- HttpUserPatchRequest,
- HttpChangePasswordRequest,
-} from '../user';
-
-import { mockStorage, sha1, mockPrepare } from './common';
-
-import defaultAvatarUrl from './default-avatar.png';
-
-let _defaultAvatar: BlobWithEtag | undefined = undefined;
-
-async function getDefaultAvatar(): Promise<BlobWithEtag> {
- if (_defaultAvatar == null) {
- const blob = (
- await axios.get<Blob>(defaultAvatarUrl, {
- responseType: 'blob',
- })
- ).data;
- const etag = await sha1(blob);
- _defaultAvatar = {
- data: blob,
- etag,
- };
- }
- return _defaultAvatar;
-}
-
-export class MockTokenError extends Error {
- constructor() {
- super('Token bad format.');
- }
-}
-
-export class MockUserNotExistError extends Error {
- constructor() {
- super('Only two user "user" and "admin".');
- }
-}
-
-export function checkUsername(
- username: string
-): asserts username is 'user' | 'admin' {
- if (!['user', 'admin'].includes(username)) throw new MockUserNotExistError();
-}
-
-export function checkToken(token: string): string {
- if (!token.startsWith('token-')) {
- throw new MockTokenError();
- }
- return token.substr(6);
-}
-
-const uniqueIdMap = {
- user: 'e4c80127d092d9b2fc19c5e04612d4c0',
- admin: '5640fa45435f9a55077b9f77c42a77bb',
-};
-
-export async function getUser(
- username: 'user' | 'admin' | string
-): Promise<HttpUser> {
- checkUsername(username);
- const savedNickname = await mockStorage.getItem<string>(
- `user.${username}.nickname`
- );
- return {
- uniqueId: uniqueIdMap[username],
- username: username,
- nickname:
- savedNickname == null || savedNickname === '' ? username : savedNickname,
- administrator: username === 'admin',
- };
-}
-
-export class MockHttpUserClient implements IHttpUserClient {
- async get(username: string): Promise<HttpUser> {
- await mockPrepare('user.get');
- return await getUser(username).catch((e) => {
- if (e instanceof MockUserNotExistError) {
- throw new HttpUserNotExistError();
- } else {
- throw e;
- }
- });
- }
-
- async patch(
- username: string,
- req: HttpUserPatchRequest,
- _token: string
- ): Promise<HttpUser> {
- await mockPrepare('user.patch');
- if (req.nickname != null) {
- await mockStorage.setItem(`user.${username}.nickname`, req.nickname);
- }
- return await getUser(username);
- }
-
- getAvatar(username: string): Promise<BlobWithEtag>;
- async getAvatar(
- username: string,
- etag?: string
- ): Promise<BlobWithEtag | NotModified> {
- await mockPrepare('user.avatar.get');
-
- const savedEtag = await mockStorage.getItem(`user.${username}.avatar.etag`);
- if (savedEtag == null) {
- return await getDefaultAvatar();
- }
-
- if (savedEtag === etag) {
- return new NotModified();
- }
-
- return {
- data: await mockStorage.getItem<Blob>(`user.${username}.avatar.data`),
- etag: await mockStorage.getItem<string>(`user.${username}.avatar.etag`),
- };
- }
-
- async putAvatar(username: string, data: Blob, _token: string): Promise<void> {
- await mockPrepare('user.avatar.put');
- const etag = await sha1(data);
- await mockStorage.setItem<Blob>(`user.${username}.avatar.data`, data);
- await mockStorage.setItem<string>(`user.${username}.avatar.etag`, etag);
- }
-
- async changePassword(
- _req: HttpChangePasswordRequest,
- _token: string
- ): Promise<void> {
- await mockPrepare('userop.changepassowrd');
- throw new Error('Not Implemented.');
- }
-}
+import axios from "axios"; + +import { BlobWithEtag, NotModified } from "../common"; +import { + IHttpUserClient, + HttpUser, + HttpUserNotExistError, + HttpUserPatchRequest, + HttpChangePasswordRequest, +} from "../user"; + +import { mockStorage, sha1, mockPrepare } from "./common"; + +import defaultAvatarUrl from "./default-avatar.png"; + +let _defaultAvatar: BlobWithEtag | undefined = undefined; + +async function getDefaultAvatar(): Promise<BlobWithEtag> { + if (_defaultAvatar == null) { + const blob = ( + await axios.get<Blob>(defaultAvatarUrl, { + responseType: "blob", + }) + ).data; + const etag = await sha1(blob); + _defaultAvatar = { + data: blob, + etag, + }; + } + return _defaultAvatar; +} + +export class MockTokenError extends Error { + constructor() { + super("Token bad format."); + } +} + +export class MockUserNotExistError extends Error { + constructor() { + super('Only two user "user" and "admin".'); + } +} + +export function checkUsername( + username: string +): asserts username is "user" | "admin" { + if (!["user", "admin"].includes(username)) throw new MockUserNotExistError(); +} + +export function checkToken(token: string): string { + if (!token.startsWith("token-")) { + throw new MockTokenError(); + } + return token.substr(6); +} + +const uniqueIdMap = { + user: "e4c80127d092d9b2fc19c5e04612d4c0", + admin: "5640fa45435f9a55077b9f77c42a77bb", +}; + +export async function getUser( + username: "user" | "admin" | string +): Promise<HttpUser> { + checkUsername(username); + const savedNickname = await mockStorage.getItem<string>( + `user.${username}.nickname` + ); + return { + uniqueId: uniqueIdMap[username], + username: username, + nickname: + savedNickname == null || savedNickname === "" ? username : savedNickname, + administrator: username === "admin", + }; +} + +export class MockHttpUserClient implements IHttpUserClient { + async get(username: string): Promise<HttpUser> { + await mockPrepare("user.get"); + return await getUser(username).catch((e) => { + if (e instanceof MockUserNotExistError) { + throw new HttpUserNotExistError(); + } else { + throw e; + } + }); + } + + async patch( + username: string, + req: HttpUserPatchRequest, + _token: string + ): Promise<HttpUser> { + await mockPrepare("user.patch"); + if (req.nickname != null) { + await mockStorage.setItem(`user.${username}.nickname`, req.nickname); + } + return await getUser(username); + } + + getAvatar(username: string): Promise<BlobWithEtag>; + async getAvatar( + username: string, + etag?: string + ): Promise<BlobWithEtag | NotModified> { + await mockPrepare("user.avatar.get"); + + const savedEtag = await mockStorage.getItem(`user.${username}.avatar.etag`); + if (savedEtag == null) { + return await getDefaultAvatar(); + } + + if (savedEtag === etag) { + return new NotModified(); + } + + return { + data: await mockStorage.getItem<Blob>(`user.${username}.avatar.data`), + etag: await mockStorage.getItem<string>(`user.${username}.avatar.etag`), + }; + } + + async putAvatar(username: string, data: Blob, _token: string): Promise<void> { + await mockPrepare("user.avatar.put"); + const etag = await sha1(data); + await mockStorage.setItem<Blob>(`user.${username}.avatar.data`, data); + await mockStorage.setItem<string>(`user.${username}.avatar.etag`, etag); + } + + async changePassword( + _req: HttpChangePasswordRequest, + _token: string + ): Promise<void> { + await mockPrepare("userop.changepassowrd"); + throw new Error("Not Implemented."); + } +} diff --git a/Timeline/ClientApp/src/app/http/timeline.ts b/Timeline/ClientApp/src/app/http/timeline.ts index c4ebdee9..4a325bca 100644 --- a/Timeline/ClientApp/src/app/http/timeline.ts +++ b/Timeline/ClientApp/src/app/http/timeline.ts @@ -1,543 +1,543 @@ -import axios, { AxiosError } from 'axios';
-
-import { updateQueryString, applyQueryParameters } from '../utilities/url';
-import {
- apiBaseUrl,
- extractResponseData,
- convertToNetworkError,
- base64,
- convertToIfStatusCodeIs,
- convertToIfErrorCodeIs,
- BlobWithEtag,
- NotModified,
- convertToNotModified,
- convertToForbiddenError,
- convertToBlobWithEtag,
-} from './common';
-import { HttpUser } from './user';
-
-export const kTimelineVisibilities = ['Public', 'Register', 'Private'] as const;
-
-export type TimelineVisibility = typeof kTimelineVisibilities[number];
-
-export interface HttpTimelineInfo {
- uniqueId: string;
- name: string;
- description: string;
- owner: HttpUser;
- visibility: TimelineVisibility;
- lastModified: Date;
- members: HttpUser[];
-}
-
-export interface HttpTimelineListQuery {
- visibility?: TimelineVisibility;
- relate?: string;
- relateType?: 'own' | 'join';
-}
-
-export interface HttpTimelinePostRequest {
- name: string;
-}
-
-export interface HttpTimelinePostTextContent {
- type: 'text';
- text: string;
-}
-
-export interface HttpTimelinePostImageContent {
- type: 'image';
-}
-
-export type HttpTimelinePostContent =
- | HttpTimelinePostTextContent
- | HttpTimelinePostImageContent;
-
-export interface HttpTimelinePostInfo {
- id: number;
- content: HttpTimelinePostContent;
- time: Date;
- lastUpdated: Date;
- author: HttpUser;
- deleted: false;
-}
-
-export interface HttpTimelineDeletedPostInfo {
- id: number;
- time: Date;
- lastUpdated: Date;
- author?: HttpUser;
- deleted: true;
-}
-
-export type HttpTimelineGenericPostInfo =
- | HttpTimelinePostInfo
- | HttpTimelineDeletedPostInfo;
-
-export interface HttpTimelinePostPostRequestTextContent {
- type: 'text';
- text: string;
-}
-
-export interface HttpTimelinePostPostRequestImageContent {
- type: 'image';
- data: Blob;
-}
-
-export type HttpTimelinePostPostRequestContent =
- | HttpTimelinePostPostRequestTextContent
- | HttpTimelinePostPostRequestImageContent;
-
-export interface HttpTimelinePostPostRequest {
- content: HttpTimelinePostPostRequestContent;
- time?: Date;
-}
-
-export interface HttpTimelinePatchRequest {
- visibility?: TimelineVisibility;
- description?: string;
-}
-
-export class HttpTimelineNotExistError extends Error {
- constructor(public innerError?: AxiosError) {
- super();
- }
-}
-
-export class HttpTimelinePostNotExistError extends Error {
- constructor(public innerError?: AxiosError) {
- super();
- }
-}
-
-export class HttpTimelineNameConflictError extends Error {
- constructor(public innerError?: AxiosError) {
- super();
- }
-}
-
-//-------------------- begin: internal model --------------------
-
-interface RawTimelineInfo {
- uniqueId: string;
- name: string;
- description: string;
- owner: HttpUser;
- visibility: TimelineVisibility;
- lastModified: string;
- members: HttpUser[];
-}
-
-interface RawTimelinePostTextContent {
- type: 'text';
- text: string;
-}
-
-interface RawTimelinePostImageContent {
- type: 'image';
- url: string;
-}
-
-type RawTimelinePostContent =
- | RawTimelinePostTextContent
- | RawTimelinePostImageContent;
-
-interface RawTimelinePostInfo {
- id: number;
- content: HttpTimelinePostContent;
- time: string;
- lastUpdated: string;
- author: HttpUser;
- deleted: false;
-}
-
-interface RawTimelineDeletedPostInfo {
- id: number;
- time: string;
- lastUpdated: string;
- author: HttpUser;
- deleted: true;
-}
-
-type RawTimelineGenericPostInfo =
- | RawTimelinePostInfo
- | RawTimelineDeletedPostInfo;
-
-interface RawTimelinePostPostRequestTextContent {
- type: 'text';
- text: string;
-}
-
-interface RawTimelinePostPostRequestImageContent {
- type: 'image';
- data: string;
-}
-
-type RawTimelinePostPostRequestContent =
- | RawTimelinePostPostRequestTextContent
- | RawTimelinePostPostRequestImageContent;
-
-interface RawTimelinePostPostRequest {
- content: RawTimelinePostPostRequestContent;
- time?: string;
-}
-
-//-------------------- end: internal model --------------------
-
-function processRawTimelineInfo(raw: RawTimelineInfo): HttpTimelineInfo {
- return {
- ...raw,
- lastModified: new Date(raw.lastModified),
- };
-}
-
-function processRawTimelinePostInfo(
- raw: RawTimelinePostInfo
-): HttpTimelinePostInfo;
-function processRawTimelinePostInfo(
- raw: RawTimelineGenericPostInfo
-): HttpTimelineGenericPostInfo;
-function processRawTimelinePostInfo(
- raw: RawTimelineGenericPostInfo
-): HttpTimelineGenericPostInfo {
- return {
- ...raw,
- time: new Date(raw.time),
- lastUpdated: new Date(raw.lastUpdated),
- };
-}
-
-export interface IHttpTimelineClient {
- listTimeline(query: HttpTimelineListQuery): Promise<HttpTimelineInfo[]>;
- getTimeline(timelineName: string): Promise<HttpTimelineInfo>;
- getTimeline(
- timelineName: string,
- query: {
- checkUniqueId?: string;
- }
- ): Promise<HttpTimelineInfo>;
- getTimeline(
- timelineName: string,
- query: {
- checkUniqueId?: string;
- ifModifiedSince: Date;
- }
- ): Promise<HttpTimelineInfo | NotModified>;
- postTimeline(
- req: HttpTimelinePostRequest,
- token: string
- ): Promise<HttpTimelineInfo>;
- patchTimeline(
- timelineName: string,
- req: HttpTimelinePatchRequest,
- token: string
- ): Promise<HttpTimelineInfo>;
- deleteTimeline(timelineName: string, token: string): Promise<void>;
- memberPut(
- timelineName: string,
- username: string,
- token: string
- ): Promise<void>;
- memberDelete(
- timelineName: string,
- username: string,
- token: string
- ): Promise<void>;
- listPost(
- timelineName: string,
- token?: string
- ): Promise<HttpTimelinePostInfo[]>;
- listPost(
- timelineName: string,
- token: string | undefined,
- query: {
- modifiedSince?: Date;
- includeDeleted?: false;
- }
- ): Promise<HttpTimelinePostInfo[]>;
- listPost(
- timelineName: string,
- token: string | undefined,
- query: {
- modifiedSince?: Date;
- includeDeleted: true;
- }
- ): Promise<HttpTimelineGenericPostInfo[]>;
- getPostData(
- timelineName: string,
- postId: number,
- token?: string
- ): Promise<BlobWithEtag>;
- getPostData(
- timelineName: string,
- postId: number,
- token: string | undefined,
- etag: string
- ): Promise<BlobWithEtag | NotModified>;
- postPost(
- timelineName: string,
- req: HttpTimelinePostPostRequest,
- token: string
- ): Promise<HttpTimelinePostInfo>;
- deletePost(
- timelineName: string,
- postId: number,
- token: string
- ): Promise<void>;
-}
-
-export class HttpTimelineClient implements IHttpTimelineClient {
- listTimeline(query: HttpTimelineListQuery): Promise<HttpTimelineInfo[]> {
- return axios
- .get<RawTimelineInfo[]>(
- applyQueryParameters(`${apiBaseUrl}/timelines`, query)
- )
- .then(extractResponseData)
- .then((list) => list.map(processRawTimelineInfo))
- .catch(convertToNetworkError);
- }
-
- getTimeline(timelineName: string): Promise<HttpTimelineInfo>;
- getTimeline(
- timelineName: string,
- query: {
- checkUniqueId?: string;
- }
- ): Promise<HttpTimelineInfo>;
- getTimeline(
- timelineName: string,
- query: {
- checkUniqueId?: string;
- ifModifiedSince: Date;
- }
- ): Promise<HttpTimelineInfo | NotModified>;
- getTimeline(
- timelineName: string,
- query?: {
- checkUniqueId?: string;
- ifModifiedSince?: Date;
- }
- ): Promise<HttpTimelineInfo | NotModified> {
- return axios
- .get<RawTimelineInfo>(
- applyQueryParameters(`${apiBaseUrl}/timelines/${timelineName}`, query)
- )
- .then((res) => {
- if (res.status === 304) {
- return new NotModified();
- } else {
- return processRawTimelineInfo(res.data);
- }
- })
- .catch(convertToIfStatusCodeIs(404, HttpTimelineNotExistError))
- .catch(convertToNetworkError);
- }
-
- postTimeline(
- req: HttpTimelinePostRequest,
- token: string
- ): Promise<HttpTimelineInfo> {
- return axios
- .post<RawTimelineInfo>(`${apiBaseUrl}/timelines?token=${token}`, req)
- .then(extractResponseData)
- .then(processRawTimelineInfo)
- .catch(convertToIfErrorCodeIs(11040101, HttpTimelineNameConflictError))
- .catch(convertToNetworkError);
- }
-
- patchTimeline(
- timelineName: string,
- req: HttpTimelinePatchRequest,
- token: string
- ): Promise<HttpTimelineInfo> {
- return axios
- .patch<RawTimelineInfo>(
- `${apiBaseUrl}/timelines/${timelineName}?token=${token}`,
- req
- )
- .then(extractResponseData)
- .then(processRawTimelineInfo)
- .catch(convertToNetworkError);
- }
-
- deleteTimeline(timelineName: string, token: string): Promise<void> {
- return axios
- .delete(`${apiBaseUrl}/timelines/${timelineName}?token=${token}`)
- .catch(convertToNetworkError)
- .then();
- }
-
- memberPut(
- timelineName: string,
- username: string,
- token: string
- ): Promise<void> {
- return axios
- .put(
- `${apiBaseUrl}/timelines/${timelineName}/members/${username}?token=${token}`
- )
- .catch(convertToNetworkError)
- .then();
- }
-
- memberDelete(
- timelineName: string,
- username: string,
- token: string
- ): Promise<void> {
- return axios
- .delete(
- `${apiBaseUrl}/timelines/${timelineName}/members/${username}?token=${token}`
- )
- .catch(convertToNetworkError)
- .then();
- }
-
- listPost(
- timelineName: string,
- token?: string
- ): Promise<HttpTimelinePostInfo[]>;
- listPost(
- timelineName: string,
- token: string | undefined,
- query: {
- modifiedSince?: Date;
- includeDeleted?: false;
- }
- ): Promise<HttpTimelinePostInfo[]>;
- listPost(
- timelineName: string,
- token: string | undefined,
- query: {
- modifiedSince?: Date;
- includeDeleted: true;
- }
- ): Promise<HttpTimelineGenericPostInfo[]>;
- listPost(
- timelineName: string,
- token?: string,
- query?: {
- modifiedSince?: Date;
- includeDeleted?: boolean;
- }
- ): Promise<HttpTimelineGenericPostInfo[]> {
- let url = `${apiBaseUrl}/timelines/${timelineName}/posts`;
- url = updateQueryString('token', token, url);
- if (query != null) {
- if (query.modifiedSince != null) {
- url = updateQueryString(
- 'modifiedSince',
- query.modifiedSince.toISOString(),
- url
- );
- }
- if (query.includeDeleted != null) {
- url = updateQueryString(
- 'includeDeleted',
- query.includeDeleted ? 'true' : 'false',
- url
- );
- }
- }
-
- return axios
- .get<RawTimelineGenericPostInfo[]>(url)
- .then(extractResponseData)
- .catch(convertToIfStatusCodeIs(404, HttpTimelineNotExistError))
- .catch(convertToForbiddenError)
- .catch(convertToNetworkError)
- .then((rawPosts) =>
- rawPosts.map((raw) => processRawTimelinePostInfo(raw))
- );
- }
-
- getPostData(
- timelineName: string,
- postId: number,
- token: string
- ): Promise<BlobWithEtag>;
- getPostData(
- timelineName: string,
- postId: number,
- token?: string,
- etag?: string
- ): Promise<BlobWithEtag | NotModified> {
- const headers =
- etag != null
- ? {
- 'If-None-Match': etag,
- }
- : undefined;
-
- let url = `${apiBaseUrl}/timelines/${timelineName}/posts/${postId}/data`;
- url = updateQueryString('token', token, url);
-
- return axios
- .get(url, {
- responseType: 'blob',
- headers,
- })
- .then(convertToBlobWithEtag)
- .catch(convertToNotModified)
- .catch(convertToIfStatusCodeIs(404, HttpTimelinePostNotExistError))
- .catch(convertToNetworkError);
- }
-
- async postPost(
- timelineName: string,
- req: HttpTimelinePostPostRequest,
- token: string
- ): Promise<HttpTimelinePostInfo> {
- let content: RawTimelinePostPostRequestContent;
- if (req.content.type === 'image') {
- const base64Data = await base64(req.content.data);
- content = {
- ...req.content,
- data: base64Data,
- } as RawTimelinePostPostRequestImageContent;
- } else {
- content = req.content;
- }
- const rawReq: RawTimelinePostPostRequest = {
- content,
- };
- if (req.time != null) {
- rawReq.time = req.time.toISOString();
- }
- return await axios
- .post<RawTimelinePostInfo>(
- `${apiBaseUrl}/timelines/${timelineName}/posts?token=${token}`,
- rawReq
- )
- .then(extractResponseData)
- .catch(convertToNetworkError)
- .then((rawPost) => processRawTimelinePostInfo(rawPost));
- }
-
- deletePost(
- timelineName: string,
- postId: number,
- token: string
- ): Promise<void> {
- return axios
- .delete(
- `${apiBaseUrl}/timelines/${timelineName}/posts/${postId}?token=${token}`
- )
- .catch(convertToNetworkError)
- .then();
- }
-}
-
-let client: IHttpTimelineClient = new HttpTimelineClient();
-
-export function getHttpTimelineClient(): IHttpTimelineClient {
- return client;
-}
-
-export function setHttpTimelineClient(
- newClient: IHttpTimelineClient
-): IHttpTimelineClient {
- const old = client;
- client = newClient;
- return old;
-}
+import axios, { AxiosError } from "axios"; + +import { updateQueryString, applyQueryParameters } from "../utilities/url"; +import { + apiBaseUrl, + extractResponseData, + convertToNetworkError, + base64, + convertToIfStatusCodeIs, + convertToIfErrorCodeIs, + BlobWithEtag, + NotModified, + convertToNotModified, + convertToForbiddenError, + convertToBlobWithEtag, +} from "./common"; +import { HttpUser } from "./user"; + +export const kTimelineVisibilities = ["Public", "Register", "Private"] as const; + +export type TimelineVisibility = typeof kTimelineVisibilities[number]; + +export interface HttpTimelineInfo { + uniqueId: string; + name: string; + description: string; + owner: HttpUser; + visibility: TimelineVisibility; + lastModified: Date; + members: HttpUser[]; +} + +export interface HttpTimelineListQuery { + visibility?: TimelineVisibility; + relate?: string; + relateType?: "own" | "join"; +} + +export interface HttpTimelinePostRequest { + name: string; +} + +export interface HttpTimelinePostTextContent { + type: "text"; + text: string; +} + +export interface HttpTimelinePostImageContent { + type: "image"; +} + +export type HttpTimelinePostContent = + | HttpTimelinePostTextContent + | HttpTimelinePostImageContent; + +export interface HttpTimelinePostInfo { + id: number; + content: HttpTimelinePostContent; + time: Date; + lastUpdated: Date; + author: HttpUser; + deleted: false; +} + +export interface HttpTimelineDeletedPostInfo { + id: number; + time: Date; + lastUpdated: Date; + author?: HttpUser; + deleted: true; +} + +export type HttpTimelineGenericPostInfo = + | HttpTimelinePostInfo + | HttpTimelineDeletedPostInfo; + +export interface HttpTimelinePostPostRequestTextContent { + type: "text"; + text: string; +} + +export interface HttpTimelinePostPostRequestImageContent { + type: "image"; + data: Blob; +} + +export type HttpTimelinePostPostRequestContent = + | HttpTimelinePostPostRequestTextContent + | HttpTimelinePostPostRequestImageContent; + +export interface HttpTimelinePostPostRequest { + content: HttpTimelinePostPostRequestContent; + time?: Date; +} + +export interface HttpTimelinePatchRequest { + visibility?: TimelineVisibility; + description?: string; +} + +export class HttpTimelineNotExistError extends Error { + constructor(public innerError?: AxiosError) { + super(); + } +} + +export class HttpTimelinePostNotExistError extends Error { + constructor(public innerError?: AxiosError) { + super(); + } +} + +export class HttpTimelineNameConflictError extends Error { + constructor(public innerError?: AxiosError) { + super(); + } +} + +//-------------------- begin: internal model -------------------- + +interface RawTimelineInfo { + uniqueId: string; + name: string; + description: string; + owner: HttpUser; + visibility: TimelineVisibility; + lastModified: string; + members: HttpUser[]; +} + +interface RawTimelinePostTextContent { + type: "text"; + text: string; +} + +interface RawTimelinePostImageContent { + type: "image"; + url: string; +} + +type RawTimelinePostContent = + | RawTimelinePostTextContent + | RawTimelinePostImageContent; + +interface RawTimelinePostInfo { + id: number; + content: HttpTimelinePostContent; + time: string; + lastUpdated: string; + author: HttpUser; + deleted: false; +} + +interface RawTimelineDeletedPostInfo { + id: number; + time: string; + lastUpdated: string; + author: HttpUser; + deleted: true; +} + +type RawTimelineGenericPostInfo = + | RawTimelinePostInfo + | RawTimelineDeletedPostInfo; + +interface RawTimelinePostPostRequestTextContent { + type: "text"; + text: string; +} + +interface RawTimelinePostPostRequestImageContent { + type: "image"; + data: string; +} + +type RawTimelinePostPostRequestContent = + | RawTimelinePostPostRequestTextContent + | RawTimelinePostPostRequestImageContent; + +interface RawTimelinePostPostRequest { + content: RawTimelinePostPostRequestContent; + time?: string; +} + +//-------------------- end: internal model -------------------- + +function processRawTimelineInfo(raw: RawTimelineInfo): HttpTimelineInfo { + return { + ...raw, + lastModified: new Date(raw.lastModified), + }; +} + +function processRawTimelinePostInfo( + raw: RawTimelinePostInfo +): HttpTimelinePostInfo; +function processRawTimelinePostInfo( + raw: RawTimelineGenericPostInfo +): HttpTimelineGenericPostInfo; +function processRawTimelinePostInfo( + raw: RawTimelineGenericPostInfo +): HttpTimelineGenericPostInfo { + return { + ...raw, + time: new Date(raw.time), + lastUpdated: new Date(raw.lastUpdated), + }; +} + +export interface IHttpTimelineClient { + listTimeline(query: HttpTimelineListQuery): Promise<HttpTimelineInfo[]>; + getTimeline(timelineName: string): Promise<HttpTimelineInfo>; + getTimeline( + timelineName: string, + query: { + checkUniqueId?: string; + } + ): Promise<HttpTimelineInfo>; + getTimeline( + timelineName: string, + query: { + checkUniqueId?: string; + ifModifiedSince: Date; + } + ): Promise<HttpTimelineInfo | NotModified>; + postTimeline( + req: HttpTimelinePostRequest, + token: string + ): Promise<HttpTimelineInfo>; + patchTimeline( + timelineName: string, + req: HttpTimelinePatchRequest, + token: string + ): Promise<HttpTimelineInfo>; + deleteTimeline(timelineName: string, token: string): Promise<void>; + memberPut( + timelineName: string, + username: string, + token: string + ): Promise<void>; + memberDelete( + timelineName: string, + username: string, + token: string + ): Promise<void>; + listPost( + timelineName: string, + token?: string + ): Promise<HttpTimelinePostInfo[]>; + listPost( + timelineName: string, + token: string | undefined, + query: { + modifiedSince?: Date; + includeDeleted?: false; + } + ): Promise<HttpTimelinePostInfo[]>; + listPost( + timelineName: string, + token: string | undefined, + query: { + modifiedSince?: Date; + includeDeleted: true; + } + ): Promise<HttpTimelineGenericPostInfo[]>; + getPostData( + timelineName: string, + postId: number, + token?: string + ): Promise<BlobWithEtag>; + getPostData( + timelineName: string, + postId: number, + token: string | undefined, + etag: string + ): Promise<BlobWithEtag | NotModified>; + postPost( + timelineName: string, + req: HttpTimelinePostPostRequest, + token: string + ): Promise<HttpTimelinePostInfo>; + deletePost( + timelineName: string, + postId: number, + token: string + ): Promise<void>; +} + +export class HttpTimelineClient implements IHttpTimelineClient { + listTimeline(query: HttpTimelineListQuery): Promise<HttpTimelineInfo[]> { + return axios + .get<RawTimelineInfo[]>( + applyQueryParameters(`${apiBaseUrl}/timelines`, query) + ) + .then(extractResponseData) + .then((list) => list.map(processRawTimelineInfo)) + .catch(convertToNetworkError); + } + + getTimeline(timelineName: string): Promise<HttpTimelineInfo>; + getTimeline( + timelineName: string, + query: { + checkUniqueId?: string; + } + ): Promise<HttpTimelineInfo>; + getTimeline( + timelineName: string, + query: { + checkUniqueId?: string; + ifModifiedSince: Date; + } + ): Promise<HttpTimelineInfo | NotModified>; + getTimeline( + timelineName: string, + query?: { + checkUniqueId?: string; + ifModifiedSince?: Date; + } + ): Promise<HttpTimelineInfo | NotModified> { + return axios + .get<RawTimelineInfo>( + applyQueryParameters(`${apiBaseUrl}/timelines/${timelineName}`, query) + ) + .then((res) => { + if (res.status === 304) { + return new NotModified(); + } else { + return processRawTimelineInfo(res.data); + } + }) + .catch(convertToIfStatusCodeIs(404, HttpTimelineNotExistError)) + .catch(convertToNetworkError); + } + + postTimeline( + req: HttpTimelinePostRequest, + token: string + ): Promise<HttpTimelineInfo> { + return axios + .post<RawTimelineInfo>(`${apiBaseUrl}/timelines?token=${token}`, req) + .then(extractResponseData) + .then(processRawTimelineInfo) + .catch(convertToIfErrorCodeIs(11040101, HttpTimelineNameConflictError)) + .catch(convertToNetworkError); + } + + patchTimeline( + timelineName: string, + req: HttpTimelinePatchRequest, + token: string + ): Promise<HttpTimelineInfo> { + return axios + .patch<RawTimelineInfo>( + `${apiBaseUrl}/timelines/${timelineName}?token=${token}`, + req + ) + .then(extractResponseData) + .then(processRawTimelineInfo) + .catch(convertToNetworkError); + } + + deleteTimeline(timelineName: string, token: string): Promise<void> { + return axios + .delete(`${apiBaseUrl}/timelines/${timelineName}?token=${token}`) + .catch(convertToNetworkError) + .then(); + } + + memberPut( + timelineName: string, + username: string, + token: string + ): Promise<void> { + return axios + .put( + `${apiBaseUrl}/timelines/${timelineName}/members/${username}?token=${token}` + ) + .catch(convertToNetworkError) + .then(); + } + + memberDelete( + timelineName: string, + username: string, + token: string + ): Promise<void> { + return axios + .delete( + `${apiBaseUrl}/timelines/${timelineName}/members/${username}?token=${token}` + ) + .catch(convertToNetworkError) + .then(); + } + + listPost( + timelineName: string, + token?: string + ): Promise<HttpTimelinePostInfo[]>; + listPost( + timelineName: string, + token: string | undefined, + query: { + modifiedSince?: Date; + includeDeleted?: false; + } + ): Promise<HttpTimelinePostInfo[]>; + listPost( + timelineName: string, + token: string | undefined, + query: { + modifiedSince?: Date; + includeDeleted: true; + } + ): Promise<HttpTimelineGenericPostInfo[]>; + listPost( + timelineName: string, + token?: string, + query?: { + modifiedSince?: Date; + includeDeleted?: boolean; + } + ): Promise<HttpTimelineGenericPostInfo[]> { + let url = `${apiBaseUrl}/timelines/${timelineName}/posts`; + url = updateQueryString("token", token, url); + if (query != null) { + if (query.modifiedSince != null) { + url = updateQueryString( + "modifiedSince", + query.modifiedSince.toISOString(), + url + ); + } + if (query.includeDeleted != null) { + url = updateQueryString( + "includeDeleted", + query.includeDeleted ? "true" : "false", + url + ); + } + } + + return axios + .get<RawTimelineGenericPostInfo[]>(url) + .then(extractResponseData) + .catch(convertToIfStatusCodeIs(404, HttpTimelineNotExistError)) + .catch(convertToForbiddenError) + .catch(convertToNetworkError) + .then((rawPosts) => + rawPosts.map((raw) => processRawTimelinePostInfo(raw)) + ); + } + + getPostData( + timelineName: string, + postId: number, + token: string + ): Promise<BlobWithEtag>; + getPostData( + timelineName: string, + postId: number, + token?: string, + etag?: string + ): Promise<BlobWithEtag | NotModified> { + const headers = + etag != null + ? { + "If-None-Match": etag, + } + : undefined; + + let url = `${apiBaseUrl}/timelines/${timelineName}/posts/${postId}/data`; + url = updateQueryString("token", token, url); + + return axios + .get(url, { + responseType: "blob", + headers, + }) + .then(convertToBlobWithEtag) + .catch(convertToNotModified) + .catch(convertToIfStatusCodeIs(404, HttpTimelinePostNotExistError)) + .catch(convertToNetworkError); + } + + async postPost( + timelineName: string, + req: HttpTimelinePostPostRequest, + token: string + ): Promise<HttpTimelinePostInfo> { + let content: RawTimelinePostPostRequestContent; + if (req.content.type === "image") { + const base64Data = await base64(req.content.data); + content = { + ...req.content, + data: base64Data, + } as RawTimelinePostPostRequestImageContent; + } else { + content = req.content; + } + const rawReq: RawTimelinePostPostRequest = { + content, + }; + if (req.time != null) { + rawReq.time = req.time.toISOString(); + } + return await axios + .post<RawTimelinePostInfo>( + `${apiBaseUrl}/timelines/${timelineName}/posts?token=${token}`, + rawReq + ) + .then(extractResponseData) + .catch(convertToNetworkError) + .then((rawPost) => processRawTimelinePostInfo(rawPost)); + } + + deletePost( + timelineName: string, + postId: number, + token: string + ): Promise<void> { + return axios + .delete( + `${apiBaseUrl}/timelines/${timelineName}/posts/${postId}?token=${token}` + ) + .catch(convertToNetworkError) + .then(); + } +} + +let client: IHttpTimelineClient = new HttpTimelineClient(); + +export function getHttpTimelineClient(): IHttpTimelineClient { + return client; +} + +export function setHttpTimelineClient( + newClient: IHttpTimelineClient +): IHttpTimelineClient { + const old = client; + client = newClient; + return old; +} diff --git a/Timeline/ClientApp/src/app/http/token.ts b/Timeline/ClientApp/src/app/http/token.ts index 26f7891f..ae0cf3f6 100644 --- a/Timeline/ClientApp/src/app/http/token.ts +++ b/Timeline/ClientApp/src/app/http/token.ts @@ -1,72 +1,72 @@ -import axios, { AxiosError } from 'axios';
-
-import {
- apiBaseUrl,
- convertToNetworkError,
- convertToIfErrorCodeIs,
- extractResponseData,
-} from './common';
-import { HttpUser } from './user';
-
-export interface HttpCreateTokenRequest {
- username: string;
- password: string;
- expire: number;
-}
-
-export interface HttpCreateTokenResponse {
- token: string;
- user: HttpUser;
-}
-
-export interface HttpVerifyTokenRequest {
- token: string;
-}
-
-export interface HttpVerifyTokenResponse {
- user: HttpUser;
-}
-
-export class HttpCreateTokenBadCredentialError extends Error {
- constructor(public innerError?: AxiosError) {
- super();
- }
-}
-
-export interface IHttpTokenClient {
- create(req: HttpCreateTokenRequest): Promise<HttpCreateTokenResponse>;
- verify(req: HttpVerifyTokenRequest): Promise<HttpVerifyTokenResponse>;
-}
-
-export class HttpTokenClient implements IHttpTokenClient {
- create(req: HttpCreateTokenRequest): Promise<HttpCreateTokenResponse> {
- return axios
- .post<HttpCreateTokenResponse>(`${apiBaseUrl}/token/create`, req)
- .then(extractResponseData)
- .catch(
- convertToIfErrorCodeIs(11010101, HttpCreateTokenBadCredentialError)
- )
- .catch(convertToNetworkError);
- }
-
- verify(req: HttpVerifyTokenRequest): Promise<HttpVerifyTokenResponse> {
- return axios
- .post<HttpVerifyTokenResponse>(`${apiBaseUrl}/token/verify`, req)
- .then(extractResponseData)
- .catch(convertToNetworkError);
- }
-}
-
-let client: IHttpTokenClient = new HttpTokenClient();
-
-export function getHttpTokenClient(): IHttpTokenClient {
- return client;
-}
-
-export function setHttpTokenClient(
- newClient: IHttpTokenClient
-): IHttpTokenClient {
- const old = client;
- client = newClient;
- return old;
-}
+import axios, { AxiosError } from "axios"; + +import { + apiBaseUrl, + convertToNetworkError, + convertToIfErrorCodeIs, + extractResponseData, +} from "./common"; +import { HttpUser } from "./user"; + +export interface HttpCreateTokenRequest { + username: string; + password: string; + expire: number; +} + +export interface HttpCreateTokenResponse { + token: string; + user: HttpUser; +} + +export interface HttpVerifyTokenRequest { + token: string; +} + +export interface HttpVerifyTokenResponse { + user: HttpUser; +} + +export class HttpCreateTokenBadCredentialError extends Error { + constructor(public innerError?: AxiosError) { + super(); + } +} + +export interface IHttpTokenClient { + create(req: HttpCreateTokenRequest): Promise<HttpCreateTokenResponse>; + verify(req: HttpVerifyTokenRequest): Promise<HttpVerifyTokenResponse>; +} + +export class HttpTokenClient implements IHttpTokenClient { + create(req: HttpCreateTokenRequest): Promise<HttpCreateTokenResponse> { + return axios + .post<HttpCreateTokenResponse>(`${apiBaseUrl}/token/create`, req) + .then(extractResponseData) + .catch( + convertToIfErrorCodeIs(11010101, HttpCreateTokenBadCredentialError) + ) + .catch(convertToNetworkError); + } + + verify(req: HttpVerifyTokenRequest): Promise<HttpVerifyTokenResponse> { + return axios + .post<HttpVerifyTokenResponse>(`${apiBaseUrl}/token/verify`, req) + .then(extractResponseData) + .catch(convertToNetworkError); + } +} + +let client: IHttpTokenClient = new HttpTokenClient(); + +export function getHttpTokenClient(): IHttpTokenClient { + return client; +} + +export function setHttpTokenClient( + newClient: IHttpTokenClient +): IHttpTokenClient { + const old = client; + client = newClient; + return old; +} diff --git a/Timeline/ClientApp/src/app/http/user.ts b/Timeline/ClientApp/src/app/http/user.ts index baa831aa..a0a02cce 100644 --- a/Timeline/ClientApp/src/app/http/user.ts +++ b/Timeline/ClientApp/src/app/http/user.ts @@ -1,134 +1,134 @@ -import axios, { AxiosError } from 'axios';
-
-import {
- apiBaseUrl,
- convertToNetworkError,
- extractResponseData,
- convertToIfStatusCodeIs,
- convertToIfErrorCodeIs,
- NotModified,
- BlobWithEtag,
- convertToBlobWithEtag,
- convertToNotModified,
-} from './common';
-
-export interface HttpUser {
- uniqueId: string;
- username: string;
- administrator: boolean;
- nickname: string;
-}
-
-export interface HttpUserPatchRequest {
- nickname?: string;
-}
-
-export interface HttpChangePasswordRequest {
- oldPassword: string;
- newPassword: string;
-}
-
-export class HttpUserNotExistError extends Error {
- constructor(public innerError?: AxiosError) {
- super();
- }
-}
-
-export class HttpChangePasswordBadCredentialError extends Error {
- constructor(public innerError?: AxiosError) {
- super();
- }
-}
-
-export interface IHttpUserClient {
- get(username: string): Promise<HttpUser>;
- patch(
- username: string,
- req: HttpUserPatchRequest,
- token: string
- ): Promise<HttpUser>;
- getAvatar(username: string): Promise<BlobWithEtag>;
- getAvatar(
- username: string,
- etag: string
- ): Promise<BlobWithEtag | NotModified>;
- putAvatar(username: string, data: Blob, token: string): Promise<void>;
- changePassword(req: HttpChangePasswordRequest, token: string): Promise<void>;
-}
-
-export class HttpUserClient implements IHttpUserClient {
- get(username: string): Promise<HttpUser> {
- return axios
- .get<HttpUser>(`${apiBaseUrl}/users/${username}`)
- .then(extractResponseData)
- .catch(convertToIfStatusCodeIs(404, HttpUserNotExistError))
- .catch(convertToNetworkError);
- }
-
- patch(
- username: string,
- req: HttpUserPatchRequest,
- token: string
- ): Promise<HttpUser> {
- return axios
- .patch<HttpUser>(`${apiBaseUrl}/users/${username}?token=${token}`, req)
- .then(extractResponseData)
- .catch(convertToNetworkError);
- }
-
- getAvatar(username: string): Promise<BlobWithEtag>;
- getAvatar(
- username: string,
- etag?: string
- ): Promise<BlobWithEtag | NotModified> {
- const headers =
- etag != null
- ? {
- 'If-None-Match': etag,
- }
- : undefined;
-
- return axios
- .get(`${apiBaseUrl}/users/${username}/avatar`, {
- responseType: 'blob',
- headers,
- })
- .then(convertToBlobWithEtag)
- .catch(convertToNotModified)
- .catch(convertToIfStatusCodeIs(404, HttpUserNotExistError))
- .catch(convertToNetworkError);
- }
-
- putAvatar(username: string, data: Blob, token: string): Promise<void> {
- return axios
- .put(`${apiBaseUrl}/users/${username}/avatar?token=${token}`, data, {
- headers: {
- 'Content-Type': data.type,
- },
- })
- .catch(convertToNetworkError)
- .then();
- }
-
- changePassword(req: HttpChangePasswordRequest, token: string): Promise<void> {
- return axios
- .post(`${apiBaseUrl}/userop/changepassword?token=${token}`, req)
- .catch(
- convertToIfErrorCodeIs(11020201, HttpChangePasswordBadCredentialError)
- )
- .catch(convertToNetworkError)
- .then();
- }
-}
-
-let client: IHttpUserClient = new HttpUserClient();
-
-export function getHttpUserClient(): IHttpUserClient {
- return client;
-}
-
-export function setHttpUserClient(newClient: IHttpUserClient): IHttpUserClient {
- const old = client;
- client = newClient;
- return old;
-}
+import axios, { AxiosError } from "axios"; + +import { + apiBaseUrl, + convertToNetworkError, + extractResponseData, + convertToIfStatusCodeIs, + convertToIfErrorCodeIs, + NotModified, + BlobWithEtag, + convertToBlobWithEtag, + convertToNotModified, +} from "./common"; + +export interface HttpUser { + uniqueId: string; + username: string; + administrator: boolean; + nickname: string; +} + +export interface HttpUserPatchRequest { + nickname?: string; +} + +export interface HttpChangePasswordRequest { + oldPassword: string; + newPassword: string; +} + +export class HttpUserNotExistError extends Error { + constructor(public innerError?: AxiosError) { + super(); + } +} + +export class HttpChangePasswordBadCredentialError extends Error { + constructor(public innerError?: AxiosError) { + super(); + } +} + +export interface IHttpUserClient { + get(username: string): Promise<HttpUser>; + patch( + username: string, + req: HttpUserPatchRequest, + token: string + ): Promise<HttpUser>; + getAvatar(username: string): Promise<BlobWithEtag>; + getAvatar( + username: string, + etag: string + ): Promise<BlobWithEtag | NotModified>; + putAvatar(username: string, data: Blob, token: string): Promise<void>; + changePassword(req: HttpChangePasswordRequest, token: string): Promise<void>; +} + +export class HttpUserClient implements IHttpUserClient { + get(username: string): Promise<HttpUser> { + return axios + .get<HttpUser>(`${apiBaseUrl}/users/${username}`) + .then(extractResponseData) + .catch(convertToIfStatusCodeIs(404, HttpUserNotExistError)) + .catch(convertToNetworkError); + } + + patch( + username: string, + req: HttpUserPatchRequest, + token: string + ): Promise<HttpUser> { + return axios + .patch<HttpUser>(`${apiBaseUrl}/users/${username}?token=${token}`, req) + .then(extractResponseData) + .catch(convertToNetworkError); + } + + getAvatar(username: string): Promise<BlobWithEtag>; + getAvatar( + username: string, + etag?: string + ): Promise<BlobWithEtag | NotModified> { + const headers = + etag != null + ? { + "If-None-Match": etag, + } + : undefined; + + return axios + .get(`${apiBaseUrl}/users/${username}/avatar`, { + responseType: "blob", + headers, + }) + .then(convertToBlobWithEtag) + .catch(convertToNotModified) + .catch(convertToIfStatusCodeIs(404, HttpUserNotExistError)) + .catch(convertToNetworkError); + } + + putAvatar(username: string, data: Blob, token: string): Promise<void> { + return axios + .put(`${apiBaseUrl}/users/${username}/avatar?token=${token}`, data, { + headers: { + "Content-Type": data.type, + }, + }) + .catch(convertToNetworkError) + .then(); + } + + changePassword(req: HttpChangePasswordRequest, token: string): Promise<void> { + return axios + .post(`${apiBaseUrl}/userop/changepassword?token=${token}`, req) + .catch( + convertToIfErrorCodeIs(11020201, HttpChangePasswordBadCredentialError) + ) + .catch(convertToNetworkError) + .then(); + } +} + +let client: IHttpUserClient = new HttpUserClient(); + +export function getHttpUserClient(): IHttpUserClient { + return client; +} + +export function setHttpUserClient(newClient: IHttpUserClient): IHttpUserClient { + const old = client; + client = newClient; + return old; +} diff --git a/Timeline/ClientApp/src/app/i18n.ts b/Timeline/ClientApp/src/app/i18n.ts index aa293819..cdced7bf 100644 --- a/Timeline/ClientApp/src/app/i18n.ts +++ b/Timeline/ClientApp/src/app/i18n.ts @@ -1,79 +1,79 @@ -import i18n, { BackendModule, ResourceKey } from 'i18next';
-import LanguageDetector from 'i18next-browser-languagedetector';
-import { initReactI18next } from 'react-i18next';
-
-const backend: BackendModule = {
- type: 'backend',
- async read(language, namespace, callback) {
- function error(message: string): void {
- callback(new Error(message), false);
- }
-
- function success(result: ResourceKey): void {
- callback(null, result);
- }
-
- if (namespace !== 'translation') {
- error("Namespace must be 'translation'.");
- }
-
- if (language === 'en') {
- const res = (
- await import(
- /* webpackChunkName: "locales-en" */ './locales/en/translation'
- )
- ).default;
- success(res);
- } else if (language === 'zh-cn' || language === 'zh') {
- const res = (
- await import(
- /* webpackChunkName: "locales-zh" */ './locales/zh/translation'
- )
- ).default;
- success(res);
- } else {
- error(`Language ${language} is not supported.`);
- }
- },
- init() {}, // eslint-disable-line @typescript-eslint/no-empty-function
- create() {}, // eslint-disable-line @typescript-eslint/no-empty-function
-};
-
-export const i18nPromise = i18n
- .use(LanguageDetector)
- .use(backend)
- .use(initReactI18next) // bind react-i18next to the instance
- .init({
- fallbackLng: false,
- lowerCaseLng: true,
-
- debug: process.env.NODE_ENV === 'development',
-
- interpolation: {
- escapeValue: false, // not needed for react!!
- },
-
- // react i18next special options (optional)
- // override if needed - omit if ok with defaults
- /*
- react: {
- bindI18n: 'languageChanged',
- bindI18nStore: '',
- transEmptyNodeValue: '',
- transSupportBasicHtmlNodes: true,
- transKeepBasicHtmlNodesFor: ['br', 'strong', 'i'],
- useSuspense: true,
- }
- */
- });
-
-if (module.hot) {
- module.hot.accept(
- ['./locales/en/translation', './locales/zh/translation'],
- () => {
- void i18n.reloadResources();
- }
- );
-}
-
-export default i18n;
+import i18n, { BackendModule, ResourceKey } from "i18next"; +import LanguageDetector from "i18next-browser-languagedetector"; +import { initReactI18next } from "react-i18next"; + +const backend: BackendModule = { + type: "backend", + async read(language, namespace, callback) { + function error(message: string): void { + callback(new Error(message), false); + } + + function success(result: ResourceKey): void { + callback(null, result); + } + + if (namespace !== "translation") { + error("Namespace must be 'translation'."); + } + + if (language === "en") { + const res = ( + await import( + /* webpackChunkName: "locales-en" */ "./locales/en/translation" + ) + ).default; + success(res); + } else if (language === "zh-cn" || language === "zh") { + const res = ( + await import( + /* webpackChunkName: "locales-zh" */ "./locales/zh/translation" + ) + ).default; + success(res); + } else { + error(`Language ${language} is not supported.`); + } + }, + init() {}, // eslint-disable-line @typescript-eslint/no-empty-function + create() {}, // eslint-disable-line @typescript-eslint/no-empty-function +}; + +export const i18nPromise = i18n + .use(LanguageDetector) + .use(backend) + .use(initReactI18next) // bind react-i18next to the instance + .init({ + fallbackLng: false, + lowerCaseLng: true, + + debug: process.env.NODE_ENV === "development", + + interpolation: { + escapeValue: false, // not needed for react!! + }, + + // react i18next special options (optional) + // override if needed - omit if ok with defaults + /* + react: { + bindI18n: 'languageChanged', + bindI18nStore: '', + transEmptyNodeValue: '', + transSupportBasicHtmlNodes: true, + transKeepBasicHtmlNodesFor: ['br', 'strong', 'i'], + useSuspense: true, + } + */ + }); + +if (module.hot) { + module.hot.accept( + ["./locales/en/translation", "./locales/zh/translation"], + () => { + void i18n.reloadResources(); + } + ); +} + +export default i18n; diff --git a/Timeline/ClientApp/src/app/index.sass b/Timeline/ClientApp/src/app/index.sass index 927a1f5a..ef0b03ba 100644 --- a/Timeline/ClientApp/src/app/index.sass +++ b/Timeline/ClientApp/src/app/index.sass @@ -1,82 +1,82 @@ -@import '~bootstrap/scss/bootstrap'
-
-@import './common/common'
-@import './common/alert'
-@import './home/home'
-@import './about/about'
-@import './timeline/timeline'
-@import './timeline/timeline-ui'
-@import './user/user-page'
-
-body
- margin: 0
-
-#app
- display: flex
- flex-direction: column
-
-small
- line-height: 1.2
-
-.width-1px
- width: 1px
-
-.flex-fix-length
- flex-grow: 0
- flex-shrink: 0
-
-.position-lt
- left: 0
- top: 0
-
-.position-rb
- right: 0
- bottom: 0
-
-.app-bar
- z-index: 1035
-
-.avatar
- width: 60px
-
-.avatar.large
- width: 100px
-
-.avatar.small
- width: 40px
-
-.mt-appbar
- margin-top: 56px
-
-.icon-button
- font-size: 1.4em
-
-.large-icon-button
- font-size: 1.6em
-
-.cursor-pointer
- cursor: pointer
-
-textarea
- resize: none
-
-.white-space-no-wrap
- white-space: nowrap
-
-.cru-card
- @extend .shadow
- @extend .border
- @extend .border-primary
- @extend .rounded
- @extend .bg-light
-
-.full-viewport-center-child
- position: fixed
- width: 100vw
- height: 100vh
- display: flex
- justify-content: center
- align-items: center
-
-.text-orange
- color: $orange
+@import '~bootstrap/scss/bootstrap' + +@import './common/common' +@import './common/alert' +@import './home/home' +@import './about/about' +@import './timeline/timeline' +@import './timeline/timeline-ui' +@import './user/user-page' + +body + margin: 0 + +#app + display: flex + flex-direction: column + +small + line-height: 1.2 + +.width-1px + width: 1px + +.flex-fix-length + flex-grow: 0 + flex-shrink: 0 + +.position-lt + left: 0 + top: 0 + +.position-rb + right: 0 + bottom: 0 + +.app-bar + z-index: 1035 + +.avatar + width: 60px + +.avatar.large + width: 100px + +.avatar.small + width: 40px + +.mt-appbar + margin-top: 56px + +.icon-button + font-size: 1.4em + +.large-icon-button + font-size: 1.6em + +.cursor-pointer + cursor: pointer + +textarea + resize: none + +.white-space-no-wrap + white-space: nowrap + +.cru-card + @extend .shadow + @extend .border + @extend .border-primary + @extend .rounded + @extend .bg-light + +.full-viewport-center-child + position: fixed + width: 100vw + height: 100vh + display: flex + justify-content: center + align-items: center + +.text-orange + color: $orange diff --git a/Timeline/ClientApp/src/app/index.tsx b/Timeline/ClientApp/src/app/index.tsx index 70b28704..00a75a4a 100644 --- a/Timeline/ClientApp/src/app/index.tsx +++ b/Timeline/ClientApp/src/app/index.tsx @@ -1,15 +1,15 @@ -import 'regenerator-runtime';
-import 'core-js/modules/es.promise';
-import 'core-js/modules/es.array.iterator';
-import 'pepjs';
-
-import React from 'react';
-import ReactDOM from 'react-dom';
-
-import './index.sass';
-
-import './i18n';
-
-import App from './App';
-
-ReactDOM.render(<App />, document.getElementById('app'));
+import "regenerator-runtime"; +import "core-js/modules/es.promise"; +import "core-js/modules/es.array.iterator"; +import "pepjs"; + +import React from "react"; +import ReactDOM from "react-dom"; + +import "./index.sass"; + +import "./i18n"; + +import App from "./App"; + +ReactDOM.render(<App />, document.getElementById("app")); diff --git a/Timeline/ClientApp/src/app/locales/en/translation.ts b/Timeline/ClientApp/src/app/locales/en/translation.ts index e7f395e1..c7f33d1e 100644 --- a/Timeline/ClientApp/src/app/locales/en/translation.ts +++ b/Timeline/ClientApp/src/app/locales/en/translation.ts @@ -1,202 +1,202 @@ -import TranslationResource from '../scheme';
-
-const translation: TranslationResource = {
- welcome: 'Welcome!',
- search: 'Search',
- loadFailReload: 'Load failed, click <1>here</1> to reload.',
- serviceWorker: {
- availableOffline:
- 'Timeline is now cached in your computer and you can use it offline. 🎉🎉🎉',
- upgradePrompt: 'App is getting a new version!',
- upgradeNow: 'Update Now',
- upgradeSuccess:
- 'Congratulations! App update succeeded! Still you can use it offline. 🎉🎉🎉',
- externalActivatedPrompt:
- 'A new version of app is activated. Please refresh the page. Or it may be broken.',
- reloadNow: 'Refresh Now',
- },
- nav: {
- settings: 'Settings',
- login: 'Login',
- about: 'About',
- },
- chooseImage: 'Choose a image',
- loadImageError: 'Failed to load image.',
- home: {
- go: 'Go!',
- allTimeline: 'All Timelines',
- joinTimeline: 'Joined Timelines',
- ownTimeline: 'Owned Timelines',
- offlinePrompt:
- 'Oh oh, it seems you are offline. Here list some timelines cached locally. You can view them or click <1>here</1> to refresh.',
- createButton: 'Create Timeline',
- createDialog: {
- title: 'Create Timeline!',
- name: 'Name',
- nameFormat:
- 'Name must consist of only letter including non-English letter, digit, hyphen(-) and underline(_) and be no longer than 26.',
- badFormat: 'Bad format.',
- noEmpty: 'Empty is not allowed.',
- tooLong: 'Too long.',
- },
- },
- operationDialog: {
- retry: 'Retry',
- nextStep: 'Next',
- previousStep: 'Previous',
- confirm: 'Confirm',
- cancel: 'Cancel',
- ok: 'OK!',
- processing: 'Processing...',
- success: 'Success!',
- error: 'An error occured.',
- },
- timeline: {
- messageCantSee: 'Sorry, you are not allowed to see this timeline.😅',
- userNotExist: 'The user does not exist!',
- timelineNotExist: 'The timeline does not exist!',
- manage: 'Manage',
- memberButton: 'Member',
- send: 'Send',
- deletePostFailed: 'Failed to delete post.',
- sendPostFailed: 'Failed to send post.',
- visibility: {
- public: 'public to everyone',
- register: 'only registed people can see',
- private: 'only members can see',
- },
- visibilityTooltip: {
- public:
- 'Everyone including those without accounts can see content of the timeline.',
- register:
- 'Only those who have an account and logined can see content of the timeline.',
- private: 'Only members of this timeline can see content of the timeline.',
- },
- dialogChangeProperty: {
- title: 'Change Timeline Properties',
- visibility: 'Visibility',
- description: 'Description',
- },
- member: {
- alreadyMember: 'The user is already a member.',
- add: 'Add',
- remove: 'Remove',
- },
- manageItem: {
- nickname: 'Nickname',
- avatar: 'Avatar',
- property: 'Timeline Property',
- member: 'Timeline Member',
- delete: 'Delete Timeline',
- },
- deleteDialog: {
- title: 'Delete Timeline',
- inputPrompt:
- 'This is a dangerous action. If you are sure to delete timeline<1>{{name}}</1>, please input its name below and click confirm button.',
- notMatch: 'Name does not match.',
- },
- postSyncState: {
- syncing: 'Syncing',
- synced: 'Synced',
- offline: 'Offline',
- },
- post: {
- deleteDialog: {
- title: 'Confirm Delete',
- prompt:
- 'Are you sure to delete the post? This operation is not recoverable.',
- },
- },
- },
- user: {
- username: 'username',
- password: 'password',
- login: 'login',
- rememberMe: 'Remember Me',
- welcomeBack: 'Welcome back!',
- verifyTokenFailed: 'User login info is expired. Please login again!',
- verifyTokenFailedNetwork:
- 'Verifying user login info failed. Please check your network and refresh page!',
- },
- login: {
- emptyUsername: "Username can't be empty.",
- emptyPassword: "Password can't be empty.",
- badCredential: 'Username or password is invalid.',
- alreadyLogin: 'Already login! Redirect to home page in 3s!',
- },
- userPage: {
- dialogChangeNickname: {
- title: 'Change Nickname',
- inputLabel: 'New nickname',
- },
- dialogChangeAvatar: {
- title: 'Change Avatar',
- previewImgAlt: 'preview',
- prompt: {
- select: 'Please select a picture.',
- crop: 'Please crop the picture.',
- processingCrop: 'Cropping picture...',
- uploading: 'Uploading...',
- preview: 'Please preview avatar',
- },
- upload: 'upload',
- },
- },
- settings: {
- subheaders: {
- account: 'Account',
- customization: 'Customization',
- },
- languagePrimary: 'Choose display language.',
- languageSecondary:
- 'You language preference will be saved locally. Next time you visit this page, last language option will be used.',
- changePassword: "Change account's password.",
- logout: 'Log out this account.',
- gotoSelf:
- 'Click here to go to timeline of myself to change nickname and avatar.',
- dialogChangePassword: {
- title: 'Change Password',
- prompt:
- 'You are changing your password. You need to input the correct old password. After change, you need to login again and all old login will be invalid.',
- inputOldPassword: 'Old password',
- inputNewPassword: 'New password',
- inputRetypeNewPassword: 'Retype new password',
- errorEmptyOldPassword: "Old password can't be empty.",
- errorEmptyNewPassword: "New password can't be empty.",
- errorRetypeNotMatch: 'Password retyped does not match.',
- },
- dialogConfirmLogout: {
- title: 'Confirm Logout',
- prompt:
- 'Are you sure to log out? All cached data in the browser will be deleted.',
- },
- },
- about: {
- author: {
- title: 'Site Developer',
- fullname: 'Fullname: ',
- nickname: 'Nickname: ',
- introduction: 'Introduction: ',
- introductionContent: 'A programmer coding based on coincidence',
- links: 'Links: ',
- },
- site: {
- title: 'Site Information',
- content:
- 'The name of this site is <1>Timeline</1>, which is a Web App with <3>timeline</3> as its core concept. Its frontend and backend are both developed by <5>me</5>, and open source on GitHub. It is relatively easy to deploy it on your own server, which is also one of my goals. Welcome to comment anything in GitHub repository.',
- repo: 'GitHub Repo',
- },
- credits: {
- title: 'Credits',
- content:
- 'Timeline is works standing on shoulders of gaints. Special appreciation for many open source projects listed below or not. Related licenses could be found in GitHub repository.',
- frontend: 'Frontend: ',
- backend: 'Backend: ',
- },
- },
- admin: {
- title: 'admin',
- },
-};
-
-export default translation;
+import TranslationResource from "../scheme"; + +const translation: TranslationResource = { + welcome: "Welcome!", + search: "Search", + loadFailReload: "Load failed, click <1>here</1> to reload.", + serviceWorker: { + availableOffline: + "Timeline is now cached in your computer and you can use it offline. 🎉🎉🎉", + upgradePrompt: "App is getting a new version!", + upgradeNow: "Update Now", + upgradeSuccess: + "Congratulations! App update succeeded! Still you can use it offline. 🎉🎉🎉", + externalActivatedPrompt: + "A new version of app is activated. Please refresh the page. Or it may be broken.", + reloadNow: "Refresh Now", + }, + nav: { + settings: "Settings", + login: "Login", + about: "About", + }, + chooseImage: "Choose a image", + loadImageError: "Failed to load image.", + home: { + go: "Go!", + allTimeline: "All Timelines", + joinTimeline: "Joined Timelines", + ownTimeline: "Owned Timelines", + offlinePrompt: + "Oh oh, it seems you are offline. Here list some timelines cached locally. You can view them or click <1>here</1> to refresh.", + createButton: "Create Timeline", + createDialog: { + title: "Create Timeline!", + name: "Name", + nameFormat: + "Name must consist of only letter including non-English letter, digit, hyphen(-) and underline(_) and be no longer than 26.", + badFormat: "Bad format.", + noEmpty: "Empty is not allowed.", + tooLong: "Too long.", + }, + }, + operationDialog: { + retry: "Retry", + nextStep: "Next", + previousStep: "Previous", + confirm: "Confirm", + cancel: "Cancel", + ok: "OK!", + processing: "Processing...", + success: "Success!", + error: "An error occured.", + }, + timeline: { + messageCantSee: "Sorry, you are not allowed to see this timeline.😅", + userNotExist: "The user does not exist!", + timelineNotExist: "The timeline does not exist!", + manage: "Manage", + memberButton: "Member", + send: "Send", + deletePostFailed: "Failed to delete post.", + sendPostFailed: "Failed to send post.", + visibility: { + public: "public to everyone", + register: "only registed people can see", + private: "only members can see", + }, + visibilityTooltip: { + public: + "Everyone including those without accounts can see content of the timeline.", + register: + "Only those who have an account and logined can see content of the timeline.", + private: "Only members of this timeline can see content of the timeline.", + }, + dialogChangeProperty: { + title: "Change Timeline Properties", + visibility: "Visibility", + description: "Description", + }, + member: { + alreadyMember: "The user is already a member.", + add: "Add", + remove: "Remove", + }, + manageItem: { + nickname: "Nickname", + avatar: "Avatar", + property: "Timeline Property", + member: "Timeline Member", + delete: "Delete Timeline", + }, + deleteDialog: { + title: "Delete Timeline", + inputPrompt: + "This is a dangerous action. If you are sure to delete timeline<1>{{name}}</1>, please input its name below and click confirm button.", + notMatch: "Name does not match.", + }, + postSyncState: { + syncing: "Syncing", + synced: "Synced", + offline: "Offline", + }, + post: { + deleteDialog: { + title: "Confirm Delete", + prompt: + "Are you sure to delete the post? This operation is not recoverable.", + }, + }, + }, + user: { + username: "username", + password: "password", + login: "login", + rememberMe: "Remember Me", + welcomeBack: "Welcome back!", + verifyTokenFailed: "User login info is expired. Please login again!", + verifyTokenFailedNetwork: + "Verifying user login info failed. Please check your network and refresh page!", + }, + login: { + emptyUsername: "Username can't be empty.", + emptyPassword: "Password can't be empty.", + badCredential: "Username or password is invalid.", + alreadyLogin: "Already login! Redirect to home page in 3s!", + }, + userPage: { + dialogChangeNickname: { + title: "Change Nickname", + inputLabel: "New nickname", + }, + dialogChangeAvatar: { + title: "Change Avatar", + previewImgAlt: "preview", + prompt: { + select: "Please select a picture.", + crop: "Please crop the picture.", + processingCrop: "Cropping picture...", + uploading: "Uploading...", + preview: "Please preview avatar", + }, + upload: "upload", + }, + }, + settings: { + subheaders: { + account: "Account", + customization: "Customization", + }, + languagePrimary: "Choose display language.", + languageSecondary: + "You language preference will be saved locally. Next time you visit this page, last language option will be used.", + changePassword: "Change account's password.", + logout: "Log out this account.", + gotoSelf: + "Click here to go to timeline of myself to change nickname and avatar.", + dialogChangePassword: { + title: "Change Password", + prompt: + "You are changing your password. You need to input the correct old password. After change, you need to login again and all old login will be invalid.", + inputOldPassword: "Old password", + inputNewPassword: "New password", + inputRetypeNewPassword: "Retype new password", + errorEmptyOldPassword: "Old password can't be empty.", + errorEmptyNewPassword: "New password can't be empty.", + errorRetypeNotMatch: "Password retyped does not match.", + }, + dialogConfirmLogout: { + title: "Confirm Logout", + prompt: + "Are you sure to log out? All cached data in the browser will be deleted.", + }, + }, + about: { + author: { + title: "Site Developer", + fullname: "Fullname: ", + nickname: "Nickname: ", + introduction: "Introduction: ", + introductionContent: "A programmer coding based on coincidence", + links: "Links: ", + }, + site: { + title: "Site Information", + content: + "The name of this site is <1>Timeline</1>, which is a Web App with <3>timeline</3> as its core concept. Its frontend and backend are both developed by <5>me</5>, and open source on GitHub. It is relatively easy to deploy it on your own server, which is also one of my goals. Welcome to comment anything in GitHub repository.", + repo: "GitHub Repo", + }, + credits: { + title: "Credits", + content: + "Timeline is works standing on shoulders of gaints. Special appreciation for many open source projects listed below or not. Related licenses could be found in GitHub repository.", + frontend: "Frontend: ", + backend: "Backend: ", + }, + }, + admin: { + title: "admin", + }, +}; + +export default translation; diff --git a/Timeline/ClientApp/src/app/locales/scheme.ts b/Timeline/ClientApp/src/app/locales/scheme.ts index bbbc2686..9e3534ac 100644 --- a/Timeline/ClientApp/src/app/locales/scheme.ts +++ b/Timeline/ClientApp/src/app/locales/scheme.ts @@ -1,182 +1,182 @@ -export default interface TranslationResource {
- welcome: string;
- search: string;
- chooseImage: string;
- loadImageError: string;
- loadFailReload: string;
- serviceWorker: {
- availableOffline: string;
- upgradePrompt: string;
- upgradeNow: string;
- upgradeSuccess: string;
- externalActivatedPrompt: string;
- reloadNow: string;
- };
- nav: {
- settings: string;
- login: string;
- about: string;
- };
- home: {
- go: string;
- allTimeline: string;
- joinTimeline: string;
- ownTimeline: string;
- offlinePrompt: string;
- createButton: string;
- createDialog: {
- title: string;
- name: string;
- nameFormat: string;
- badFormat: string;
- noEmpty: string;
- tooLong: string;
- };
- };
- operationDialog: {
- retry: string;
- nextStep: string;
- previousStep: string;
- confirm: string;
- cancel: string;
- ok: string;
- processing: string;
- success: string;
- error: string;
- };
- timeline: {
- messageCantSee: string;
- userNotExist: string;
- timelineNotExist: string;
- manage: string;
- memberButton: string;
- send: string;
- deletePostFailed: string;
- sendPostFailed: string;
- visibility: {
- public: string;
- register: string;
- private: string;
- };
- visibilityTooltip: {
- public: string;
- register: string;
- private: string;
- };
- dialogChangeProperty: {
- title: string;
- visibility: string;
- description: string;
- };
- member: {
- alreadyMember: string;
- add: string;
- remove: string;
- };
- manageItem: {
- nickname: string;
- avatar: string;
- property: string;
- member: string;
- delete: string;
- };
- deleteDialog: {
- title: string;
- inputPrompt: string;
- notMatch: string;
- };
- postSyncState: {
- syncing: string;
- synced: string;
- offline: string;
- };
- post: {
- deleteDialog: {
- title: string;
- prompt: string;
- };
- };
- };
- user: {
- username: string;
- password: string;
- login: string;
- rememberMe: string;
- welcomeBack: string;
- verifyTokenFailed: string;
- verifyTokenFailedNetwork: string;
- };
- login: {
- emptyUsername: string;
- emptyPassword: string;
- badCredential: string;
- alreadyLogin: string;
- };
- userPage: {
- dialogChangeNickname: {
- title: string;
- inputLabel: string;
- };
- dialogChangeAvatar: {
- title: string;
- previewImgAlt: string;
- prompt: {
- select: string;
- crop: string;
- processingCrop: string;
- preview: string;
- uploading: string;
- };
- upload: string;
- };
- };
- settings: {
- subheaders: {
- account: string;
- customization: string;
- };
- languagePrimary: string;
- languageSecondary: string;
- changePassword: string;
- logout: string;
- gotoSelf: string;
- dialogChangePassword: {
- title: string;
- prompt: string;
- inputOldPassword: string;
- inputNewPassword: string;
- inputRetypeNewPassword: string;
- errorEmptyOldPassword: string;
- errorEmptyNewPassword: string;
- errorRetypeNotMatch: string;
- };
- dialogConfirmLogout: {
- title: string;
- prompt: string;
- };
- };
- about: {
- author: {
- title: string;
- fullname: string;
- nickname: string;
- introduction: string;
- introductionContent: string;
- links: string;
- };
- site: {
- title: string;
- content: string;
- repo: string;
- };
- credits: {
- title: string;
- content: string;
- frontend: string;
- backend: string;
- };
- };
- admin: {
- title: string;
- };
-}
+export default interface TranslationResource { + welcome: string; + search: string; + chooseImage: string; + loadImageError: string; + loadFailReload: string; + serviceWorker: { + availableOffline: string; + upgradePrompt: string; + upgradeNow: string; + upgradeSuccess: string; + externalActivatedPrompt: string; + reloadNow: string; + }; + nav: { + settings: string; + login: string; + about: string; + }; + home: { + go: string; + allTimeline: string; + joinTimeline: string; + ownTimeline: string; + offlinePrompt: string; + createButton: string; + createDialog: { + title: string; + name: string; + nameFormat: string; + badFormat: string; + noEmpty: string; + tooLong: string; + }; + }; + operationDialog: { + retry: string; + nextStep: string; + previousStep: string; + confirm: string; + cancel: string; + ok: string; + processing: string; + success: string; + error: string; + }; + timeline: { + messageCantSee: string; + userNotExist: string; + timelineNotExist: string; + manage: string; + memberButton: string; + send: string; + deletePostFailed: string; + sendPostFailed: string; + visibility: { + public: string; + register: string; + private: string; + }; + visibilityTooltip: { + public: string; + register: string; + private: string; + }; + dialogChangeProperty: { + title: string; + visibility: string; + description: string; + }; + member: { + alreadyMember: string; + add: string; + remove: string; + }; + manageItem: { + nickname: string; + avatar: string; + property: string; + member: string; + delete: string; + }; + deleteDialog: { + title: string; + inputPrompt: string; + notMatch: string; + }; + postSyncState: { + syncing: string; + synced: string; + offline: string; + }; + post: { + deleteDialog: { + title: string; + prompt: string; + }; + }; + }; + user: { + username: string; + password: string; + login: string; + rememberMe: string; + welcomeBack: string; + verifyTokenFailed: string; + verifyTokenFailedNetwork: string; + }; + login: { + emptyUsername: string; + emptyPassword: string; + badCredential: string; + alreadyLogin: string; + }; + userPage: { + dialogChangeNickname: { + title: string; + inputLabel: string; + }; + dialogChangeAvatar: { + title: string; + previewImgAlt: string; + prompt: { + select: string; + crop: string; + processingCrop: string; + preview: string; + uploading: string; + }; + upload: string; + }; + }; + settings: { + subheaders: { + account: string; + customization: string; + }; + languagePrimary: string; + languageSecondary: string; + changePassword: string; + logout: string; + gotoSelf: string; + dialogChangePassword: { + title: string; + prompt: string; + inputOldPassword: string; + inputNewPassword: string; + inputRetypeNewPassword: string; + errorEmptyOldPassword: string; + errorEmptyNewPassword: string; + errorRetypeNotMatch: string; + }; + dialogConfirmLogout: { + title: string; + prompt: string; + }; + }; + about: { + author: { + title: string; + fullname: string; + nickname: string; + introduction: string; + introductionContent: string; + links: string; + }; + site: { + title: string; + content: string; + repo: string; + }; + credits: { + title: string; + content: string; + frontend: string; + backend: string; + }; + }; + admin: { + title: string; + }; +} diff --git a/Timeline/ClientApp/src/app/locales/zh/translation.ts b/Timeline/ClientApp/src/app/locales/zh/translation.ts index 2e0eccd5..df316366 100644 --- a/Timeline/ClientApp/src/app/locales/zh/translation.ts +++ b/Timeline/ClientApp/src/app/locales/zh/translation.ts @@ -1,195 +1,195 @@ -import TranslationResource from '../scheme';
-
-const translation: TranslationResource = {
- welcome: '欢迎!',
- search: '搜索',
- loadFailReload: '加载失败,<1>点击</1>重试。',
- serviceWorker: {
- availableOffline: 'Timeline 已经缓存在本地,你可以离线使用它。🎉🎉🎉',
- upgradePrompt: 'App 有新版本!',
- upgradeNow: '现在升级',
- upgradeSuccess: 'App 升级成功,当然,你仍可以离线使用它。 🎉🎉🎉',
- externalActivatedPrompt:
- '一个新的 App 版本已经激活,请刷新页面使用,否则页面可能会出现故障。',
- reloadNow: '立刻刷新',
- },
- nav: {
- settings: '设置',
- login: '登陆',
- about: '关于',
- },
- chooseImage: '选择一个图片',
- loadImageError: '加载图片失败',
- home: {
- go: '冲!',
- allTimeline: '所有的时间线',
- joinTimeline: '加入的时间线',
- ownTimeline: '拥有的时间线',
- offlinePrompt:
- '你好像处于离线状态。以下是一些缓存在本地的时间线。你可以查看它们或者<1>点击</1>重新获取在线信息。',
- createButton: '创建时间线',
- createDialog: {
- title: '创建时间线!',
- name: '名字',
- nameFormat:
- '名字只能由字母、汉字、数字、下划线(_)和连字符(-)构成,且长度不能超过26.',
- badFormat: '格式错误',
- noEmpty: '不能为空',
- tooLong: '太长了',
- },
- },
- operationDialog: {
- retry: '重试',
- nextStep: '下一步',
- previousStep: '上一步',
- confirm: '确定',
- cancel: '取消',
- ok: '好的!',
- processing: '处理中...',
- success: '成功!',
- error: '出错啦!',
- },
- timeline: {
- messageCantSee: '不好意思,你没有权限查看这个时间线。😅',
- userNotExist: '该用户不存在!',
- timelineNotExist: '该时间线不存在!',
- manage: '管理',
- memberButton: '成员',
- send: '发送',
- deletePostFailed: '删除消息失败。',
- sendPostFailed: '发送消息失败。',
- visibility: {
- public: '对所有人公开',
- register: '仅注册可见',
- private: '仅成员可见',
- },
- visibilityTooltip: {
- public: '所有人都可以看到这个时间线的内容,包括没有注册的人。',
- register: '只有拥有本网站的账号且登陆了的人才能看到这个时间线的内容。',
- private: '只有这个时间线的成员可以看到这个时间线的内容。',
- },
- dialogChangeProperty: {
- title: '修改时间线属性',
- visibility: '可见性',
- description: '描述',
- },
- member: {
- alreadyMember: '该用户已经是一个成员。',
- add: '添加',
- remove: '移除',
- },
- manageItem: {
- nickname: '昵称',
- avatar: '头像',
- property: '时间线属性',
- member: '时间线成员',
- delete: '删除时间线',
- },
- deleteDialog: {
- title: '删除时间线',
- inputPrompt:
- '这是一个危险的操作。如果您确认要删除时间线<1>{{name}}</1>,请在下面输入它的名字并点击确认。',
- notMatch: '名字不匹配',
- },
- postSyncState: {
- syncing: '同步中',
- synced: '同步成功',
- offline: '离线',
- },
- post: {
- deleteDialog: {
- title: '确认删除',
- prompt: '确定删除这个消息?这个操作不可撤销。',
- },
- },
- },
- user: {
- username: '用户名',
- password: '密码',
- login: '登录',
- rememberMe: '记住我',
- welcomeBack: '欢迎回来!',
- verifyTokenFailed: '用户登录信息已过期,请重新登陆!',
- verifyTokenFailedNetwork:
- '验证用户登录信息失败,请检查网络连接并刷新页面!',
- },
- login: {
- emptyUsername: '用户名不能为空。',
- emptyPassword: '密码不能为空。',
- badCredential: '用户名或密码错误。',
- alreadyLogin: '已经登陆,三秒后导航到首页!',
- },
- userPage: {
- dialogChangeNickname: {
- title: '更改昵称',
- inputLabel: '新昵称',
- },
- dialogChangeAvatar: {
- title: '修改头像',
- previewImgAlt: '预览',
- prompt: {
- select: '请选择一个图片',
- crop: '请裁剪图片',
- processingCrop: '正在裁剪图片',
- uploading: '正在上传',
- preview: '请预览图片',
- },
- upload: '上传',
- },
- },
- settings: {
- subheaders: {
- account: '账户',
- customization: '个性化',
- },
- languagePrimary: '选择显示的语言。',
- languageSecondary:
- '您的语言偏好将会存储在本地,下次浏览时将自动使用上次保存的语言选项。',
- changePassword: '更改账号的密码。',
- logout: '注销此账号。',
- gotoSelf: '点击前往个人时间线修改昵称和头像!',
- dialogChangePassword: {
- title: '修改密码',
- prompt:
- '您正在修改密码,您需要输入正确的旧密码。成功修改后您需要重新登陆,而且以前所有的登录都会失效。',
- inputOldPassword: '旧密码',
- inputNewPassword: '新密码',
- inputRetypeNewPassword: '再次输入新密码',
- errorEmptyOldPassword: '旧密码不能为空。',
- errorEmptyNewPassword: '新密码不能为空',
- errorRetypeNotMatch: '两次输入的密码不一致',
- },
- dialogConfirmLogout: {
- title: '确定注销',
- prompt: '您确定注销此账号?这将删除所有已经缓存在浏览器的数据。',
- },
- },
- about: {
- author: {
- title: '网站作者',
- fullname: '姓名:',
- nickname: '昵称:',
- introduction: '简介:',
- introductionContent: '一个基于巧合编程的代码爱好者。',
- links: '链接:',
- },
- site: {
- title: '网站信息',
- content:
- '这个网站的名字叫 <1>Timeline</1>,是一个以<3>时间线</3>为核心概念的 Web App . 它的前端和后端都是由<5>我</5>开发,并且在 GitHub 上开源。大家可以相对轻松的把它们部署在自己的服务器上,这也是我的目标之一。欢迎大家前往 GitHub 仓库提出任何意见。',
- repo: 'GitHub 仓库',
- },
- credits: {
- title: '鸣谢',
- content:
- 'Timeline 是站在巨人肩膀上的作品,感谢以下列出的和其他未列出的许多开源项目,相关 License 请在 GitHub 仓库中查看。',
- frontend: '前端:',
- backend: '后端:',
- },
- },
- admin: {
- title: '管理',
- },
-};
-
-export default translation;
+import TranslationResource from "../scheme"; + +const translation: TranslationResource = { + welcome: "欢迎!", + search: "搜索", + loadFailReload: "加载失败,<1>点击</1>重试。", + serviceWorker: { + availableOffline: "Timeline 已经缓存在本地,你可以离线使用它。🎉🎉🎉", + upgradePrompt: "App 有新版本!", + upgradeNow: "现在升级", + upgradeSuccess: "App 升级成功,当然,你仍可以离线使用它。 🎉🎉🎉", + externalActivatedPrompt: + "一个新的 App 版本已经激活,请刷新页面使用,否则页面可能会出现故障。", + reloadNow: "立刻刷新", + }, + nav: { + settings: "设置", + login: "登陆", + about: "关于", + }, + chooseImage: "选择一个图片", + loadImageError: "加载图片失败", + home: { + go: "冲!", + allTimeline: "所有的时间线", + joinTimeline: "加入的时间线", + ownTimeline: "拥有的时间线", + offlinePrompt: + "你好像处于离线状态。以下是一些缓存在本地的时间线。你可以查看它们或者<1>点击</1>重新获取在线信息。", + createButton: "创建时间线", + createDialog: { + title: "创建时间线!", + name: "名字", + nameFormat: + "名字只能由字母、汉字、数字、下划线(_)和连字符(-)构成,且长度不能超过26.", + badFormat: "格式错误", + noEmpty: "不能为空", + tooLong: "太长了", + }, + }, + operationDialog: { + retry: "重试", + nextStep: "下一步", + previousStep: "上一步", + confirm: "确定", + cancel: "取消", + ok: "好的!", + processing: "处理中...", + success: "成功!", + error: "出错啦!", + }, + timeline: { + messageCantSee: "不好意思,你没有权限查看这个时间线。😅", + userNotExist: "该用户不存在!", + timelineNotExist: "该时间线不存在!", + manage: "管理", + memberButton: "成员", + send: "发送", + deletePostFailed: "删除消息失败。", + sendPostFailed: "发送消息失败。", + visibility: { + public: "对所有人公开", + register: "仅注册可见", + private: "仅成员可见", + }, + visibilityTooltip: { + public: "所有人都可以看到这个时间线的内容,包括没有注册的人。", + register: "只有拥有本网站的账号且登陆了的人才能看到这个时间线的内容。", + private: "只有这个时间线的成员可以看到这个时间线的内容。", + }, + dialogChangeProperty: { + title: "修改时间线属性", + visibility: "可见性", + description: "描述", + }, + member: { + alreadyMember: "该用户已经是一个成员。", + add: "添加", + remove: "移除", + }, + manageItem: { + nickname: "昵称", + avatar: "头像", + property: "时间线属性", + member: "时间线成员", + delete: "删除时间线", + }, + deleteDialog: { + title: "删除时间线", + inputPrompt: + "这是一个危险的操作。如果您确认要删除时间线<1>{{name}}</1>,请在下面输入它的名字并点击确认。", + notMatch: "名字不匹配", + }, + postSyncState: { + syncing: "同步中", + synced: "同步成功", + offline: "离线", + }, + post: { + deleteDialog: { + title: "确认删除", + prompt: "确定删除这个消息?这个操作不可撤销。", + }, + }, + }, + user: { + username: "用户名", + password: "密码", + login: "登录", + rememberMe: "记住我", + welcomeBack: "欢迎回来!", + verifyTokenFailed: "用户登录信息已过期,请重新登陆!", + verifyTokenFailedNetwork: + "验证用户登录信息失败,请检查网络连接并刷新页面!", + }, + login: { + emptyUsername: "用户名不能为空。", + emptyPassword: "密码不能为空。", + badCredential: "用户名或密码错误。", + alreadyLogin: "已经登陆,三秒后导航到首页!", + }, + userPage: { + dialogChangeNickname: { + title: "更改昵称", + inputLabel: "新昵称", + }, + dialogChangeAvatar: { + title: "修改头像", + previewImgAlt: "预览", + prompt: { + select: "请选择一个图片", + crop: "请裁剪图片", + processingCrop: "正在裁剪图片", + uploading: "正在上传", + preview: "请预览图片", + }, + upload: "上传", + }, + }, + settings: { + subheaders: { + account: "账户", + customization: "个性化", + }, + languagePrimary: "选择显示的语言。", + languageSecondary: + "您的语言偏好将会存储在本地,下次浏览时将自动使用上次保存的语言选项。", + changePassword: "更改账号的密码。", + logout: "注销此账号。", + gotoSelf: "点击前往个人时间线修改昵称和头像!", + dialogChangePassword: { + title: "修改密码", + prompt: + "您正在修改密码,您需要输入正确的旧密码。成功修改后您需要重新登陆,而且以前所有的登录都会失效。", + inputOldPassword: "旧密码", + inputNewPassword: "新密码", + inputRetypeNewPassword: "再次输入新密码", + errorEmptyOldPassword: "旧密码不能为空。", + errorEmptyNewPassword: "新密码不能为空", + errorRetypeNotMatch: "两次输入的密码不一致", + }, + dialogConfirmLogout: { + title: "确定注销", + prompt: "您确定注销此账号?这将删除所有已经缓存在浏览器的数据。", + }, + }, + about: { + author: { + title: "网站作者", + fullname: "姓名:", + nickname: "昵称:", + introduction: "简介:", + introductionContent: "一个基于巧合编程的代码爱好者。", + links: "链接:", + }, + site: { + title: "网站信息", + content: + "这个网站的名字叫 <1>Timeline</1>,是一个以<3>时间线</3>为核心概念的 Web App . 它的前端和后端都是由<5>我</5>开发,并且在 GitHub 上开源。大家可以相对轻松的把它们部署在自己的服务器上,这也是我的目标之一。欢迎大家前往 GitHub 仓库提出任何意见。", + repo: "GitHub 仓库", + }, + credits: { + title: "鸣谢", + content: + "Timeline 是站在巨人肩膀上的作品,感谢以下列出的和其他未列出的许多开源项目,相关 License 请在 GitHub 仓库中查看。", + frontend: "前端:", + backend: "后端:", + }, + }, + admin: { + title: "管理", + }, +}; + +export default translation; diff --git a/Timeline/ClientApp/src/app/service-worker.tsx b/Timeline/ClientApp/src/app/service-worker.tsx index a353c809..f71b23b3 100644 --- a/Timeline/ClientApp/src/app/service-worker.tsx +++ b/Timeline/ClientApp/src/app/service-worker.tsx @@ -1,109 +1,109 @@ -import React from 'react';
-import { Button } from 'reactstrap';
-import { useTranslation } from 'react-i18next';
-
-import { pushAlert } from './common/alert-service';
-
-if ('serviceWorker' in navigator) {
- let isThisTriggerUpgrade = false;
-
- const upgradeSuccessLocalStorageKey = 'TIMELINE_UPGRADE_SUCCESS';
-
- if (window.localStorage.getItem(upgradeSuccessLocalStorageKey)) {
- pushAlert({
- message: {
- type: 'i18n',
- key: 'serviceWorker.upgradeSuccess',
- },
- type: 'success',
- });
- window.localStorage.removeItem(upgradeSuccessLocalStorageKey);
- }
-
- void import('workbox-window').then(({ Workbox, messageSW }) => {
- const wb = new Workbox('/sw.js');
- let registration: ServiceWorkerRegistration | undefined;
-
- // externalactivated is not usable but I still use its name.
- wb.addEventListener('controlling', () => {
- const upgradeReload = (): void => {
- window.localStorage.setItem(upgradeSuccessLocalStorageKey, 'true');
- window.location.reload();
- };
-
- if (isThisTriggerUpgrade) {
- upgradeReload();
- } else {
- const Message: React.FC = () => {
- const { t } = useTranslation();
- return (
- <>
- {t('serviceWorker.externalActivatedPrompt')}
- <Button color="success" size="sm" onClick={upgradeReload} outline>
- {t('serviceWorker.reloadNow')}
- </Button>
- </>
- );
- };
-
- pushAlert({
- message: Message,
- dismissTime: 'never',
- type: 'warning',
- });
- }
- });
-
- wb.addEventListener('activated', (event) => {
- if (!event.isUpdate) {
- pushAlert({
- message: {
- type: 'i18n',
- key: 'serviceWorker.availableOffline',
- },
- type: 'success',
- });
- }
- });
-
- const showSkipWaitingPrompt = (): void => {
- const upgrade = (): void => {
- isThisTriggerUpgrade = true;
- if (registration && registration.waiting) {
- // Send a message to the waiting service worker,
- // instructing it to activate.
- // Note: for this to work, you have to add a message
- // listener in your service worker. See below.
- void messageSW(registration.waiting, { type: 'SKIP_WAITING' });
- }
- };
-
- const UpgradeMessage: React.FC = () => {
- const { t } = useTranslation();
- return (
- <>
- {t('serviceWorker.upgradePrompt')}
- <Button color="success" size="sm" onClick={upgrade} outline>
- {t('serviceWorker.upgradeNow')}
- </Button>
- </>
- );
- };
-
- pushAlert({
- message: UpgradeMessage,
- dismissTime: 'never',
- type: 'success',
- });
- };
-
- // Add an event listener to detect when the registered
- // service worker has installed but is waiting to activate.
- wb.addEventListener('waiting', showSkipWaitingPrompt);
- wb.addEventListener('externalwaiting', showSkipWaitingPrompt);
-
- void wb.register().then((reg) => {
- registration = reg;
- });
- });
-}
+import React from "react"; +import { Button } from "reactstrap"; +import { useTranslation } from "react-i18next"; + +import { pushAlert } from "./common/alert-service"; + +if ("serviceWorker" in navigator) { + let isThisTriggerUpgrade = false; + + const upgradeSuccessLocalStorageKey = "TIMELINE_UPGRADE_SUCCESS"; + + if (window.localStorage.getItem(upgradeSuccessLocalStorageKey)) { + pushAlert({ + message: { + type: "i18n", + key: "serviceWorker.upgradeSuccess", + }, + type: "success", + }); + window.localStorage.removeItem(upgradeSuccessLocalStorageKey); + } + + void import("workbox-window").then(({ Workbox, messageSW }) => { + const wb = new Workbox("/sw.js"); + let registration: ServiceWorkerRegistration | undefined; + + // externalactivated is not usable but I still use its name. + wb.addEventListener("controlling", () => { + const upgradeReload = (): void => { + window.localStorage.setItem(upgradeSuccessLocalStorageKey, "true"); + window.location.reload(); + }; + + if (isThisTriggerUpgrade) { + upgradeReload(); + } else { + const Message: React.FC = () => { + const { t } = useTranslation(); + return ( + <> + {t("serviceWorker.externalActivatedPrompt")} + <Button color="success" size="sm" onClick={upgradeReload} outline> + {t("serviceWorker.reloadNow")} + </Button> + </> + ); + }; + + pushAlert({ + message: Message, + dismissTime: "never", + type: "warning", + }); + } + }); + + wb.addEventListener("activated", (event) => { + if (!event.isUpdate) { + pushAlert({ + message: { + type: "i18n", + key: "serviceWorker.availableOffline", + }, + type: "success", + }); + } + }); + + const showSkipWaitingPrompt = (): void => { + const upgrade = (): void => { + isThisTriggerUpgrade = true; + if (registration && registration.waiting) { + // Send a message to the waiting service worker, + // instructing it to activate. + // Note: for this to work, you have to add a message + // listener in your service worker. See below. + void messageSW(registration.waiting, { type: "SKIP_WAITING" }); + } + }; + + const UpgradeMessage: React.FC = () => { + const { t } = useTranslation(); + return ( + <> + {t("serviceWorker.upgradePrompt")} + <Button color="success" size="sm" onClick={upgrade} outline> + {t("serviceWorker.upgradeNow")} + </Button> + </> + ); + }; + + pushAlert({ + message: UpgradeMessage, + dismissTime: "never", + type: "success", + }); + }; + + // Add an event listener to detect when the registered + // service worker has installed but is waiting to activate. + wb.addEventListener("waiting", showSkipWaitingPrompt); + wb.addEventListener("externalwaiting", showSkipWaitingPrompt); + + void wb.register().then((reg) => { + registration = reg; + }); + }); +} diff --git a/Timeline/ClientApp/src/app/settings/Settings.tsx b/Timeline/ClientApp/src/app/settings/Settings.tsx index 13e6f4f3..dd648538 100644 --- a/Timeline/ClientApp/src/app/settings/Settings.tsx +++ b/Timeline/ClientApp/src/app/settings/Settings.tsx @@ -1,222 +1,222 @@ -import React, { useState } from 'react';
-import { useHistory } from 'react-router';
-import { useTranslation } from 'react-i18next';
-import {
- Container,
- Row,
- Col,
- Input,
- Modal,
- ModalHeader,
- ModalBody,
- ModalFooter,
- Button,
-} from 'reactstrap';
-
-import { useUser, userService } from '../data/user';
-
-import AppBar from '../common/AppBar';
-import OperationDialog, {
- OperationInputErrorInfo,
-} from '../common/OperationDialog';
-
-interface ChangePasswordDialogProps {
- open: boolean;
- close: () => void;
-}
-
-const ChangePasswordDialog: React.FC<ChangePasswordDialogProps> = (props) => {
- const history = useHistory();
- const { t } = useTranslation();
-
- const [redirect, setRedirect] = useState<boolean>(false);
-
- return (
- <OperationDialog
- open={props.open}
- title={t('settings.dialogChangePassword.title')}
- titleColor="dangerous"
- inputPrompt={t('settings.dialogChangePassword.prompt')}
- inputScheme={[
- {
- type: 'text',
- label: t('settings.dialogChangePassword.inputOldPassword'),
- password: true,
- validator: (v) =>
- v === ''
- ? 'settings.dialogChangePassword.errorEmptyOldPassword'
- : null,
- },
- {
- type: 'text',
- label: t('settings.dialogChangePassword.inputNewPassword'),
- password: true,
- validator: (v, values) => {
- const error: OperationInputErrorInfo = {};
- error[1] =
- v === ''
- ? 'settings.dialogChangePassword.errorEmptyNewPassword'
- : null;
- if (v === values[2]) {
- error[2] = null;
- } else {
- if (values[2] !== '') {
- error[2] = 'settings.dialogChangePassword.errorRetypeNotMatch';
- }
- }
- return error;
- },
- },
- {
- type: 'text',
- label: t('settings.dialogChangePassword.inputRetypeNewPassword'),
- password: true,
- validator: (v, values) =>
- v !== values[1]
- ? 'settings.dialogChangePassword.errorRetypeNotMatch'
- : null,
- },
- ]}
- onProcess={async ([oldPassword, newPassword]) => {
- await userService
- .changePassword(oldPassword as string, newPassword as string)
- .toPromise();
- await userService.logout();
- setRedirect(true);
- }}
- close={() => {
- props.close();
- if (redirect) {
- history.push('/login');
- }
- }}
- />
- );
-};
-
-const ConfirmLogoutDialog: React.FC<{
- toggle: () => void;
- onConfirm: () => void;
-}> = ({ toggle, onConfirm }) => {
- const { t } = useTranslation();
-
- return (
- <Modal isOpen centered>
- <ModalHeader className="text-danger">
- {t('settings.dialogConfirmLogout.title')}
- </ModalHeader>
- <ModalBody>{t('settings.dialogConfirmLogout.prompt')}</ModalBody>
- <ModalFooter>
- <Button color="secondary" onClick={toggle}>
- {t('operationDialog.cancel')}
- </Button>
- <Button color="danger" onClick={onConfirm}>
- {t('operationDialog.confirm')}
- </Button>
- </ModalFooter>
- </Modal>
- );
-};
-
-const Settings: React.FC = (_) => {
- const { i18n, t } = useTranslation();
- const user = useUser();
- const history = useHistory();
-
- const [dialog, setDialog] = useState<null | 'changepassword' | 'logout'>(
- null
- );
-
- const language = i18n.language.slice(0, 2);
-
- return (
- <>
- <AppBar />
- <Container fluid className="mt-appbar">
- {user ? (
- <>
- <Row className="border-bottom p-3 cursor-pointer">
- <Col xs="12">
- <h5
- onClick={() => {
- history.push(`/users/${user.username}`);
- }}
- >
- {t('settings.gotoSelf')}
- </h5>
- </Col>
- </Row>
- <Row className="border-bottom p-3 cursor-pointer">
- <Col xs="12">
- <h5
- className="text-danger"
- onClick={() => setDialog('changepassword')}
- >
- {t('settings.changePassword')}
- </h5>
- </Col>
- </Row>
- <Row className="border-bottom p-3 cursor-pointer">
- <Col xs="12">
- <h5
- className="text-danger"
- onClick={() => {
- setDialog('logout');
- }}
- >
- {t('settings.logout')}
- </h5>
- </Col>
- </Row>
- </>
- ) : null}
- <Row className="align-items-center border-bottom p-3">
- <Col xs="12" sm="auto">
- <h5>{t('settings.languagePrimary')}</h5>
- <p>{t('settings.languageSecondary')}</p>
- </Col>
- <Col xs="auto" className="ml-auto">
- <Input
- type="select"
- value={language}
- onChange={(e) => {
- void i18n.changeLanguage(e.target.value);
- }}
- >
- <option value="zh">中文</option>
- <option value="en">English</option>
- </Input>
- </Col>
- </Row>
- {(() => {
- switch (dialog) {
- case 'changepassword':
- return (
- <ChangePasswordDialog
- open
- close={() => {
- setDialog(null);
- }}
- />
- );
- case 'logout':
- return (
- <ConfirmLogoutDialog
- toggle={() => setDialog(null)}
- onConfirm={() => {
- void userService.logout().then(() => {
- history.push('/');
- });
- }}
- />
- );
- default:
- return null;
- }
- })()}
- </Container>
- </>
- );
-};
-
-export default Settings;
+import React, { useState } from "react"; +import { useHistory } from "react-router"; +import { useTranslation } from "react-i18next"; +import { + Container, + Row, + Col, + Input, + Modal, + ModalHeader, + ModalBody, + ModalFooter, + Button, +} from "reactstrap"; + +import { useUser, userService } from "../data/user"; + +import AppBar from "../common/AppBar"; +import OperationDialog, { + OperationInputErrorInfo, +} from "../common/OperationDialog"; + +interface ChangePasswordDialogProps { + open: boolean; + close: () => void; +} + +const ChangePasswordDialog: React.FC<ChangePasswordDialogProps> = (props) => { + const history = useHistory(); + const { t } = useTranslation(); + + const [redirect, setRedirect] = useState<boolean>(false); + + return ( + <OperationDialog + open={props.open} + title={t("settings.dialogChangePassword.title")} + titleColor="dangerous" + inputPrompt={t("settings.dialogChangePassword.prompt")} + inputScheme={[ + { + type: "text", + label: t("settings.dialogChangePassword.inputOldPassword"), + password: true, + validator: (v) => + v === "" + ? "settings.dialogChangePassword.errorEmptyOldPassword" + : null, + }, + { + type: "text", + label: t("settings.dialogChangePassword.inputNewPassword"), + password: true, + validator: (v, values) => { + const error: OperationInputErrorInfo = {}; + error[1] = + v === "" + ? "settings.dialogChangePassword.errorEmptyNewPassword" + : null; + if (v === values[2]) { + error[2] = null; + } else { + if (values[2] !== "") { + error[2] = "settings.dialogChangePassword.errorRetypeNotMatch"; + } + } + return error; + }, + }, + { + type: "text", + label: t("settings.dialogChangePassword.inputRetypeNewPassword"), + password: true, + validator: (v, values) => + v !== values[1] + ? "settings.dialogChangePassword.errorRetypeNotMatch" + : null, + }, + ]} + onProcess={async ([oldPassword, newPassword]) => { + await userService + .changePassword(oldPassword as string, newPassword as string) + .toPromise(); + await userService.logout(); + setRedirect(true); + }} + close={() => { + props.close(); + if (redirect) { + history.push("/login"); + } + }} + /> + ); +}; + +const ConfirmLogoutDialog: React.FC<{ + toggle: () => void; + onConfirm: () => void; +}> = ({ toggle, onConfirm }) => { + const { t } = useTranslation(); + + return ( + <Modal isOpen centered> + <ModalHeader className="text-danger"> + {t("settings.dialogConfirmLogout.title")} + </ModalHeader> + <ModalBody>{t("settings.dialogConfirmLogout.prompt")}</ModalBody> + <ModalFooter> + <Button color="secondary" onClick={toggle}> + {t("operationDialog.cancel")} + </Button> + <Button color="danger" onClick={onConfirm}> + {t("operationDialog.confirm")} + </Button> + </ModalFooter> + </Modal> + ); +}; + +const Settings: React.FC = (_) => { + const { i18n, t } = useTranslation(); + const user = useUser(); + const history = useHistory(); + + const [dialog, setDialog] = useState<null | "changepassword" | "logout">( + null + ); + + const language = i18n.language.slice(0, 2); + + return ( + <> + <AppBar /> + <Container fluid className="mt-appbar"> + {user ? ( + <> + <Row className="border-bottom p-3 cursor-pointer"> + <Col xs="12"> + <h5 + onClick={() => { + history.push(`/users/${user.username}`); + }} + > + {t("settings.gotoSelf")} + </h5> + </Col> + </Row> + <Row className="border-bottom p-3 cursor-pointer"> + <Col xs="12"> + <h5 + className="text-danger" + onClick={() => setDialog("changepassword")} + > + {t("settings.changePassword")} + </h5> + </Col> + </Row> + <Row className="border-bottom p-3 cursor-pointer"> + <Col xs="12"> + <h5 + className="text-danger" + onClick={() => { + setDialog("logout"); + }} + > + {t("settings.logout")} + </h5> + </Col> + </Row> + </> + ) : null} + <Row className="align-items-center border-bottom p-3"> + <Col xs="12" sm="auto"> + <h5>{t("settings.languagePrimary")}</h5> + <p>{t("settings.languageSecondary")}</p> + </Col> + <Col xs="auto" className="ml-auto"> + <Input + type="select" + value={language} + onChange={(e) => { + void i18n.changeLanguage(e.target.value); + }} + > + <option value="zh">中文</option> + <option value="en">English</option> + </Input> + </Col> + </Row> + {(() => { + switch (dialog) { + case "changepassword": + return ( + <ChangePasswordDialog + open + close={() => { + setDialog(null); + }} + /> + ); + case "logout": + return ( + <ConfirmLogoutDialog + toggle={() => setDialog(null)} + onConfirm={() => { + void userService.logout().then(() => { + history.push("/"); + }); + }} + /> + ); + default: + return null; + } + })()} + </Container> + </> + ); +}; + +export default Settings; diff --git a/Timeline/ClientApp/src/app/timeline/Timeline.tsx b/Timeline/ClientApp/src/app/timeline/Timeline.tsx index 7c3a93fb..780588d1 100644 --- a/Timeline/ClientApp/src/app/timeline/Timeline.tsx +++ b/Timeline/ClientApp/src/app/timeline/Timeline.tsx @@ -1,88 +1,88 @@ -import React from 'react';
-import clsx from 'clsx';
-
-import { TimelinePostInfo } from '../data/timeline';
-
-import TimelineItem from './TimelineItem';
-
-export interface TimelinePostInfoEx extends TimelinePostInfo {
- deletable: boolean;
-}
-
-export type TimelineDeleteCallback = (index: number, id: number) => void;
-
-export interface TimelineProps {
- className?: string;
- posts: TimelinePostInfoEx[];
- onDelete: TimelineDeleteCallback;
- onResize?: () => void;
- containerRef?: React.Ref<HTMLDivElement>;
-}
-
-const Timeline: React.FC<TimelineProps> = (props) => {
- const { posts, onDelete, onResize } = props;
-
- const [indexShowDeleteButton, setIndexShowDeleteButton] = React.useState<
- number
- >(-1);
-
- const onItemClick = React.useCallback(() => {
- setIndexShowDeleteButton(-1);
- }, []);
-
- const onToggleDelete = React.useMemo(() => {
- return posts.map((post, i) => {
- return post.deletable
- ? () => {
- setIndexShowDeleteButton((oldIndexShowDeleteButton) => {
- return oldIndexShowDeleteButton !== i ? i : -1;
- });
- }
- : undefined;
- });
- }, [posts]);
-
- const onItemDelete = React.useMemo(() => {
- return posts.map((post, i) => {
- return () => {
- onDelete(i, post.id);
- };
- });
- }, [posts, onDelete]);
-
- return (
- <div
- ref={props.containerRef}
- className={clsx('container-fluid timeline', props.className)}
- >
- <div className="timeline-enter-animation-mask" />
- {(() => {
- const length = posts.length;
- return posts.map((post, i) => {
- const toggleMore = onToggleDelete[i];
-
- return (
- <TimelineItem
- post={post}
- key={post.id}
- current={length - 1 === i}
- more={
- toggleMore
- ? {
- isOpen: indexShowDeleteButton === i,
- toggle: toggleMore,
- onDelete: onItemDelete[i],
- }
- : undefined
- }
- onClick={onItemClick}
- onResize={onResize}
- />
- );
- });
- })()}
- </div>
- );
-};
-
-export default Timeline;
+import React from "react"; +import clsx from "clsx"; + +import { TimelinePostInfo } from "../data/timeline"; + +import TimelineItem from "./TimelineItem"; + +export interface TimelinePostInfoEx extends TimelinePostInfo { + deletable: boolean; +} + +export type TimelineDeleteCallback = (index: number, id: number) => void; + +export interface TimelineProps { + className?: string; + posts: TimelinePostInfoEx[]; + onDelete: TimelineDeleteCallback; + onResize?: () => void; + containerRef?: React.Ref<HTMLDivElement>; +} + +const Timeline: React.FC<TimelineProps> = (props) => { + const { posts, onDelete, onResize } = props; + + const [indexShowDeleteButton, setIndexShowDeleteButton] = React.useState< + number + >(-1); + + const onItemClick = React.useCallback(() => { + setIndexShowDeleteButton(-1); + }, []); + + const onToggleDelete = React.useMemo(() => { + return posts.map((post, i) => { + return post.deletable + ? () => { + setIndexShowDeleteButton((oldIndexShowDeleteButton) => { + return oldIndexShowDeleteButton !== i ? i : -1; + }); + } + : undefined; + }); + }, [posts]); + + const onItemDelete = React.useMemo(() => { + return posts.map((post, i) => { + return () => { + onDelete(i, post.id); + }; + }); + }, [posts, onDelete]); + + return ( + <div + ref={props.containerRef} + className={clsx("container-fluid timeline", props.className)} + > + <div className="timeline-enter-animation-mask" /> + {(() => { + const length = posts.length; + return posts.map((post, i) => { + const toggleMore = onToggleDelete[i]; + + return ( + <TimelineItem + post={post} + key={post.id} + current={length - 1 === i} + more={ + toggleMore + ? { + isOpen: indexShowDeleteButton === i, + toggle: toggleMore, + onDelete: onItemDelete[i], + } + : undefined + } + onClick={onItemClick} + onResize={onResize} + /> + ); + }); + })()} + </div> + ); +}; + +export default Timeline; diff --git a/Timeline/ClientApp/src/app/timeline/TimelineDeleteDialog.tsx b/Timeline/ClientApp/src/app/timeline/TimelineDeleteDialog.tsx index 7bcea6c5..5ebbf9df 100644 --- a/Timeline/ClientApp/src/app/timeline/TimelineDeleteDialog.tsx +++ b/Timeline/ClientApp/src/app/timeline/TimelineDeleteDialog.tsx @@ -1,54 +1,54 @@ -import React from 'react';
-import { useHistory } from 'react-router';
-import { Trans } from 'react-i18next';
-
-import OperationDialog from '../common/OperationDialog';
-import { timelineService } from '../data/timeline';
-
-interface TimelineDeleteDialog {
- open: boolean;
- name: string;
- close: () => void;
-}
-
-const TimelineDeleteDialog: React.FC<TimelineDeleteDialog> = (props) => {
- const history = useHistory();
-
- const { name } = props;
-
- return (
- <OperationDialog
- open={props.open}
- close={props.close}
- title="timeline.deleteDialog.title"
- titleColor="danger"
- inputPrompt={() => {
- return (
- <Trans i18nKey="timeline.deleteDialog.inputPrompt">
- 0<code className="mx-2">{{ name }}</code>2
- </Trans>
- );
- }}
- inputScheme={[
- {
- type: 'text',
- validator: (value) => {
- if (value !== name) {
- return 'timeline.deleteDialog.notMatch';
- } else {
- return null;
- }
- },
- },
- ]}
- onProcess={() => {
- return timelineService.deleteTimeline(name).toPromise();
- }}
- onSuccessAndClose={() => {
- history.replace('/');
- }}
- />
- );
-};
-
-export default TimelineDeleteDialog;
+import React from "react"; +import { useHistory } from "react-router"; +import { Trans } from "react-i18next"; + +import OperationDialog from "../common/OperationDialog"; +import { timelineService } from "../data/timeline"; + +interface TimelineDeleteDialog { + open: boolean; + name: string; + close: () => void; +} + +const TimelineDeleteDialog: React.FC<TimelineDeleteDialog> = (props) => { + const history = useHistory(); + + const { name } = props; + + return ( + <OperationDialog + open={props.open} + close={props.close} + title="timeline.deleteDialog.title" + titleColor="danger" + inputPrompt={() => { + return ( + <Trans i18nKey="timeline.deleteDialog.inputPrompt"> + 0<code className="mx-2">{{ name }}</code>2 + </Trans> + ); + }} + inputScheme={[ + { + type: "text", + validator: (value) => { + if (value !== name) { + return "timeline.deleteDialog.notMatch"; + } else { + return null; + } + }, + }, + ]} + onProcess={() => { + return timelineService.deleteTimeline(name).toPromise(); + }} + onSuccessAndClose={() => { + history.replace("/"); + }} + /> + ); +}; + +export default TimelineDeleteDialog; diff --git a/Timeline/ClientApp/src/app/timeline/TimelineInfoCard.tsx b/Timeline/ClientApp/src/app/timeline/TimelineInfoCard.tsx index ece7d38a..3591b6f9 100644 --- a/Timeline/ClientApp/src/app/timeline/TimelineInfoCard.tsx +++ b/Timeline/ClientApp/src/app/timeline/TimelineInfoCard.tsx @@ -1,110 +1,110 @@ -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 { useAvatar } from '../data/user';
-import { timelineVisibilityTooltipTranslationMap } from '../data/timeline';
-
-import { TimelineCardComponentProps } from './TimelinePageTemplateUI';
-import BlobImage from '../common/BlobImage';
-
-export type OrdinaryTimelineManageItem = 'delete';
-
-export type TimelineInfoCardProps = TimelineCardComponentProps<
- OrdinaryTimelineManageItem
->;
-
-const TimelineInfoCard: React.FC<TimelineInfoCardProps> = (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 p-2 bg-light', props.className)}
- onTransitionEnd={notifyHeight}
- >
- <h3 className="text-primary mx-3 d-inline-block align-middle">
- {props.timeline.name}
- </h3>
- <div className="d-inline-block align-middle">
- <BlobImage
- blob={avatar}
- onLoad={notifyHeight}
- className="avatar small rounded-circle"
- />
- {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('property')}>
- {t('timeline.manageItem.property')}
- </DropdownItem>
- <DropdownItem onClick={props.onMember}>
- {t('timeline.manageItem.member')}
- </DropdownItem>
- <DropdownItem divider />
- <DropdownItem
- className="text-danger"
- onClick={() => onManage('delete')}
- >
- {t('timeline.manageItem.delete')}
- </DropdownItem>
- </DropdownMenu>
- </Dropdown>
- ) : (
- <Button color="primary" outline onClick={props.onMember}>
- {t('timeline.memberButton')}
- </Button>
- )}
- </div>
- </div>
- );
-};
-
-export default TimelineInfoCard;
+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 { useAvatar } from "../data/user"; +import { timelineVisibilityTooltipTranslationMap } from "../data/timeline"; + +import { TimelineCardComponentProps } from "./TimelinePageTemplateUI"; +import BlobImage from "../common/BlobImage"; + +export type OrdinaryTimelineManageItem = "delete"; + +export type TimelineInfoCardProps = TimelineCardComponentProps< + OrdinaryTimelineManageItem +>; + +const TimelineInfoCard: React.FC<TimelineInfoCardProps> = (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 p-2 bg-light", props.className)} + onTransitionEnd={notifyHeight} + > + <h3 className="text-primary mx-3 d-inline-block align-middle"> + {props.timeline.name} + </h3> + <div className="d-inline-block align-middle"> + <BlobImage + blob={avatar} + onLoad={notifyHeight} + className="avatar small rounded-circle" + /> + {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("property")}> + {t("timeline.manageItem.property")} + </DropdownItem> + <DropdownItem onClick={props.onMember}> + {t("timeline.manageItem.member")} + </DropdownItem> + <DropdownItem divider /> + <DropdownItem + className="text-danger" + onClick={() => onManage("delete")} + > + {t("timeline.manageItem.delete")} + </DropdownItem> + </DropdownMenu> + </Dropdown> + ) : ( + <Button color="primary" outline onClick={props.onMember}> + {t("timeline.memberButton")} + </Button> + )} + </div> + </div> + ); +}; + +export default TimelineInfoCard; diff --git a/Timeline/ClientApp/src/app/timeline/TimelineItem.tsx b/Timeline/ClientApp/src/app/timeline/TimelineItem.tsx index 727de1fe..0d62b0e7 100644 --- a/Timeline/ClientApp/src/app/timeline/TimelineItem.tsx +++ b/Timeline/ClientApp/src/app/timeline/TimelineItem.tsx @@ -1,183 +1,183 @@ -import React from 'react';
-import clsx from 'clsx';
-import {
- Row,
- Col,
- Modal,
- ModalHeader,
- ModalBody,
- ModalFooter,
- Button,
-} from 'reactstrap';
-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';
-
-const TimelinePostDeleteConfirmDialog: React.FC<{
- toggle: () => void;
- onConfirm: () => void;
-}> = ({ toggle, onConfirm }) => {
- const { t } = useTranslation();
-
- return (
- <Modal toggle={toggle} isOpen centered>
- <ModalHeader className="text-danger">
- {t('timeline.post.deleteDialog.title')}
- </ModalHeader>
- <ModalBody>{t('timeline.post.deleteDialog.prompt')}</ModalBody>
- <ModalFooter>
- <Button color="secondary" onClick={toggle}>
- {t('operationDialog.cancel')}
- </Button>
- <Button
- color="danger"
- onClick={() => {
- onConfirm();
- toggle();
- }}
- >
- {t('operationDialog.confirm')}
- </Button>
- </ModalFooter>
- </Modal>
- );
-};
-
-export interface TimelineItemProps {
- post: TimelinePostInfo;
- current?: boolean;
- more?: {
- isOpen: boolean;
- toggle: () => void;
- onDelete: () => void;
- };
- onClick?: () => void;
- onResize?: () => void;
- className?: string;
- style?: React.CSSProperties;
-}
-
-const TimelineItem: React.FC<TimelineItemProps> = (props) => {
- const { i18n } = useTranslation();
-
- const current = props.current === true;
-
- const { more, onResize } = props;
-
- const avatar = useAvatar(props.post.author.username);
-
- const [deleteDialog, setDeleteDialog] = React.useState<boolean>(false);
- const toggleDeleteDialog = React.useCallback(
- () => setDeleteDialog((old) => !old),
- []
- );
-
- return (
- <Row
- className={clsx(
- 'position-relative flex-nowrap',
- current && 'current',
- props.className
- )}
- onClick={props.onClick}
- style={props.style}
- >
- <Col className="timeline-line-area">
- <div className="timeline-line-segment start"></div>
- <div className="timeline-line-node-container">
- <div className="timeline-line-node"></div>
- </div>
- <div className="timeline-line-segment end"></div>
- {current && <div className="timeline-line-segment current-end" />}
- </Col>
- <Col className="timeline-pt-start">
- <Row className="flex-nowrap">
- <div className="col-auto flex-shrink-1 px-0">
- <Row className="ml-n3 mr-0 align-items-center">
- <span className="ml-3 text-primary white-space-no-wrap">
- {props.post.time.toLocaleString(i18n.languages)}
- </span>
- <small className="text-dark ml-3">
- {props.post.author.nickname}
- </small>
- </Row>
- </div>
- {more != null ? (
- <div className="col-auto px-2 d-flex justify-content-center align-items-center">
- <Svg
- src={chevronDownIcon}
- className="text-info icon-button"
- onClick={(e: Event) => {
- more.toggle();
- e.stopPropagation();
- }}
- />
- </div>
- ) : null}
- </Row>
- <div className="row d-block timeline-content">
- <Link
- className="float-right float-sm-left mx-2"
- to={'/users/' + props.post.author.username}
- >
- <BlobImage
- onLoad={onResize}
- blob={avatar}
- className="avatar rounded"
- />
- </Link>
- {(() => {
- const { content } = props.post;
- if (content.type === 'text') {
- return content.text;
- } else {
- return (
- <BlobImage
- onLoad={onResize}
- blob={content.data}
- className="timeline-content-image"
- />
- );
- }
- })()}
- </div>
- </Col>
- {more != null && more.isOpen ? (
- <>
- <div
- className="position-absolute position-lt w-100 h-100 mask d-flex justify-content-center align-items-center"
- onClick={more.toggle}
- >
- <Svg
- src={trashIcon}
- className="text-danger large-icon-button"
- onClick={(e: Event) => {
- toggleDeleteDialog();
- e.stopPropagation();
- }}
- />
- </div>
- {deleteDialog ? (
- <TimelinePostDeleteConfirmDialog
- toggle={() => {
- toggleDeleteDialog();
- more.toggle();
- }}
- onConfirm={more.onDelete}
- />
- ) : null}
- </>
- ) : null}
- </Row>
- );
-};
-
-export default TimelineItem;
+import React from "react"; +import clsx from "clsx"; +import { + Row, + Col, + Modal, + ModalHeader, + ModalBody, + ModalFooter, + Button, +} from "reactstrap"; +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"; + +const TimelinePostDeleteConfirmDialog: React.FC<{ + toggle: () => void; + onConfirm: () => void; +}> = ({ toggle, onConfirm }) => { + const { t } = useTranslation(); + + return ( + <Modal toggle={toggle} isOpen centered> + <ModalHeader className="text-danger"> + {t("timeline.post.deleteDialog.title")} + </ModalHeader> + <ModalBody>{t("timeline.post.deleteDialog.prompt")}</ModalBody> + <ModalFooter> + <Button color="secondary" onClick={toggle}> + {t("operationDialog.cancel")} + </Button> + <Button + color="danger" + onClick={() => { + onConfirm(); + toggle(); + }} + > + {t("operationDialog.confirm")} + </Button> + </ModalFooter> + </Modal> + ); +}; + +export interface TimelineItemProps { + post: TimelinePostInfo; + current?: boolean; + more?: { + isOpen: boolean; + toggle: () => void; + onDelete: () => void; + }; + onClick?: () => void; + onResize?: () => void; + className?: string; + style?: React.CSSProperties; +} + +const TimelineItem: React.FC<TimelineItemProps> = (props) => { + const { i18n } = useTranslation(); + + const current = props.current === true; + + const { more, onResize } = props; + + const avatar = useAvatar(props.post.author.username); + + const [deleteDialog, setDeleteDialog] = React.useState<boolean>(false); + const toggleDeleteDialog = React.useCallback( + () => setDeleteDialog((old) => !old), + [] + ); + + return ( + <Row + className={clsx( + "position-relative flex-nowrap", + current && "current", + props.className + )} + onClick={props.onClick} + style={props.style} + > + <Col className="timeline-line-area"> + <div className="timeline-line-segment start"></div> + <div className="timeline-line-node-container"> + <div className="timeline-line-node"></div> + </div> + <div className="timeline-line-segment end"></div> + {current && <div className="timeline-line-segment current-end" />} + </Col> + <Col className="timeline-pt-start"> + <Row className="flex-nowrap"> + <div className="col-auto flex-shrink-1 px-0"> + <Row className="ml-n3 mr-0 align-items-center"> + <span className="ml-3 text-primary white-space-no-wrap"> + {props.post.time.toLocaleString(i18n.languages)} + </span> + <small className="text-dark ml-3"> + {props.post.author.nickname} + </small> + </Row> + </div> + {more != null ? ( + <div className="col-auto px-2 d-flex justify-content-center align-items-center"> + <Svg + src={chevronDownIcon} + className="text-info icon-button" + onClick={(e: Event) => { + more.toggle(); + e.stopPropagation(); + }} + /> + </div> + ) : null} + </Row> + <div className="row d-block timeline-content"> + <Link + className="float-right float-sm-left mx-2" + to={"/users/" + props.post.author.username} + > + <BlobImage + onLoad={onResize} + blob={avatar} + className="avatar rounded" + /> + </Link> + {(() => { + const { content } = props.post; + if (content.type === "text") { + return content.text; + } else { + return ( + <BlobImage + onLoad={onResize} + blob={content.data} + className="timeline-content-image" + /> + ); + } + })()} + </div> + </Col> + {more != null && more.isOpen ? ( + <> + <div + className="position-absolute position-lt w-100 h-100 mask d-flex justify-content-center align-items-center" + onClick={more.toggle} + > + <Svg + src={trashIcon} + className="text-danger large-icon-button" + onClick={(e: Event) => { + toggleDeleteDialog(); + e.stopPropagation(); + }} + /> + </div> + {deleteDialog ? ( + <TimelinePostDeleteConfirmDialog + toggle={() => { + toggleDeleteDialog(); + more.toggle(); + }} + onConfirm={more.onDelete} + /> + ) : null} + </> + ) : null} + </Row> + ); +}; + +export default TimelineItem; diff --git a/Timeline/ClientApp/src/app/timeline/TimelineMember.tsx b/Timeline/ClientApp/src/app/timeline/TimelineMember.tsx index 39af412e..559750d2 100644 --- a/Timeline/ClientApp/src/app/timeline/TimelineMember.tsx +++ b/Timeline/ClientApp/src/app/timeline/TimelineMember.tsx @@ -1,219 +1,219 @@ -import React, { useState } from 'react';
-import { useTranslation } from 'react-i18next';
-import {
- Container,
- ListGroup,
- ListGroupItem,
- Modal,
- Row,
- Col,
- Button,
-} from 'reactstrap';
-
-import { User, useAvatar } from '../data/user';
-
-import SearchInput from '../common/SearchInput';
-import BlobImage from '../common/BlobImage';
-
-const TimelineMemberItem: React.FC<{
- user: User;
- owner: boolean;
- onRemove?: (username: string) => void;
-}> = ({ user, owner, onRemove }) => {
- const { t } = useTranslation();
-
- const avatar = useAvatar(user.username);
-
- return (
- <ListGroupItem className="container">
- <Row>
- <Col className="col-auto">
- <BlobImage blob={avatar} className="avatar small" />
- </Col>
- <Col>
- <Row>{user.nickname}</Row>
- <Row>
- <small>{'@' + user.username}</small>
- </Row>
- </Col>
- {(() => {
- if (owner) {
- return null;
- }
- if (onRemove == null) {
- return null;
- }
- return (
- <Button
- className="align-self-center"
- color="danger"
- onClick={() => {
- onRemove(user.username);
- }}
- >
- {t('timeline.member.remove')}
- </Button>
- );
- })()}
- </Row>
- </ListGroupItem>
- );
-};
-
-export interface TimelineMemberCallbacks {
- onCheckUser: (username: string) => Promise<User | null>;
- onAddUser: (user: User) => Promise<void>;
- onRemoveUser: (username: string) => void;
-}
-
-export interface TimelineMemberProps {
- members: User[];
- edit: TimelineMemberCallbacks | null | undefined;
-}
-
-const TimelineMember: React.FC<TimelineMemberProps> = (props) => {
- const { t } = useTranslation();
-
- const [userSearchText, setUserSearchText] = useState<string>('');
- const [userSearchState, setUserSearchState] = useState<
- | {
- type: 'user';
- data: User;
- }
- | { type: 'error'; data: string }
- | { type: 'loading' }
- | { type: 'init' }
- >({ type: 'init' });
-
- const userSearchAvatar = useAvatar(
- userSearchState.type === 'user' ? userSearchState.data.username : undefined
- );
-
- const members = props.members;
-
- return (
- <Container className="px-4">
- <ListGroup className="my-3">
- {members.map((member, index) => (
- <TimelineMemberItem
- key={member.username}
- user={member}
- owner={index === 0}
- onRemove={props.edit?.onRemoveUser}
- />
- ))}
- </ListGroup>
- {(() => {
- const edit = props.edit;
- if (edit != null) {
- return (
- <>
- <SearchInput
- value={userSearchText}
- onChange={(v) => {
- setUserSearchText(v);
- }}
- loading={userSearchState.type === 'loading'}
- onButtonClick={() => {
- if (userSearchText === '') {
- setUserSearchState({
- type: 'error',
- data: 'login.emptyUsername',
- });
- return;
- }
-
- setUserSearchState({ type: 'loading' });
- edit.onCheckUser(userSearchText).then(
- (u) => {
- if (u == null) {
- setUserSearchState({
- type: 'error',
- data: 'timeline.userNotExist',
- });
- } else {
- setUserSearchState({ type: 'user', data: u });
- }
- },
- (e) => {
- setUserSearchState({
- type: 'error',
- data: `${e as string}`,
- });
- }
- );
- }}
- />
- {(() => {
- if (userSearchState.type === 'user') {
- const u = userSearchState.data;
- const addable =
- members.findIndex((m) => m.username === u.username) === -1;
- return (
- <>
- {!addable ? (
- <p>{t('timeline.member.alreadyMember')}</p>
- ) : null}
- <Container className="mb-3">
- <Row>
- <Col className="col-auto">
- <BlobImage
- blob={userSearchAvatar}
- className="avatar small"
- />
- </Col>
- <Col>
- <Row>{u.nickname}</Row>
- <Row>
- <small>{'@' + u.username}</small>
- </Row>
- </Col>
- <Button
- color="primary"
- className="align-self-center"
- disabled={!addable}
- onClick={() => {
- void edit.onAddUser(u).then((_) => {
- setUserSearchText('');
- setUserSearchState({ type: 'init' });
- });
- }}
- >
- {t('timeline.member.add')}
- </Button>
- </Row>
- </Container>
- </>
- );
- } else if (userSearchState.type === 'error') {
- return (
- <p className="text-danger">{t(userSearchState.data)}</p>
- );
- }
- })()}
- </>
- );
- } else {
- return null;
- }
- })()}
- </Container>
- );
-};
-
-export default TimelineMember;
-
-export interface TimelineMemberDialogProps extends TimelineMemberProps {
- open: boolean;
- onClose: () => void;
-}
-
-export const TimelineMemberDialog: React.FC<TimelineMemberDialogProps> = (
- props
-) => {
- return (
- <Modal isOpen={props.open} toggle={props.onClose}>
- <TimelineMember {...props} />
- </Modal>
- );
-};
+import React, { useState } from "react"; +import { useTranslation } from "react-i18next"; +import { + Container, + ListGroup, + ListGroupItem, + Modal, + Row, + Col, + Button, +} from "reactstrap"; + +import { User, useAvatar } from "../data/user"; + +import SearchInput from "../common/SearchInput"; +import BlobImage from "../common/BlobImage"; + +const TimelineMemberItem: React.FC<{ + user: User; + owner: boolean; + onRemove?: (username: string) => void; +}> = ({ user, owner, onRemove }) => { + const { t } = useTranslation(); + + const avatar = useAvatar(user.username); + + return ( + <ListGroupItem className="container"> + <Row> + <Col className="col-auto"> + <BlobImage blob={avatar} className="avatar small" /> + </Col> + <Col> + <Row>{user.nickname}</Row> + <Row> + <small>{"@" + user.username}</small> + </Row> + </Col> + {(() => { + if (owner) { + return null; + } + if (onRemove == null) { + return null; + } + return ( + <Button + className="align-self-center" + color="danger" + onClick={() => { + onRemove(user.username); + }} + > + {t("timeline.member.remove")} + </Button> + ); + })()} + </Row> + </ListGroupItem> + ); +}; + +export interface TimelineMemberCallbacks { + onCheckUser: (username: string) => Promise<User | null>; + onAddUser: (user: User) => Promise<void>; + onRemoveUser: (username: string) => void; +} + +export interface TimelineMemberProps { + members: User[]; + edit: TimelineMemberCallbacks | null | undefined; +} + +const TimelineMember: React.FC<TimelineMemberProps> = (props) => { + const { t } = useTranslation(); + + const [userSearchText, setUserSearchText] = useState<string>(""); + const [userSearchState, setUserSearchState] = useState< + | { + type: "user"; + data: User; + } + | { type: "error"; data: string } + | { type: "loading" } + | { type: "init" } + >({ type: "init" }); + + const userSearchAvatar = useAvatar( + userSearchState.type === "user" ? userSearchState.data.username : undefined + ); + + const members = props.members; + + return ( + <Container className="px-4"> + <ListGroup className="my-3"> + {members.map((member, index) => ( + <TimelineMemberItem + key={member.username} + user={member} + owner={index === 0} + onRemove={props.edit?.onRemoveUser} + /> + ))} + </ListGroup> + {(() => { + const edit = props.edit; + if (edit != null) { + return ( + <> + <SearchInput + value={userSearchText} + onChange={(v) => { + setUserSearchText(v); + }} + loading={userSearchState.type === "loading"} + onButtonClick={() => { + if (userSearchText === "") { + setUserSearchState({ + type: "error", + data: "login.emptyUsername", + }); + return; + } + + setUserSearchState({ type: "loading" }); + edit.onCheckUser(userSearchText).then( + (u) => { + if (u == null) { + setUserSearchState({ + type: "error", + data: "timeline.userNotExist", + }); + } else { + setUserSearchState({ type: "user", data: u }); + } + }, + (e) => { + setUserSearchState({ + type: "error", + data: `${e as string}`, + }); + } + ); + }} + /> + {(() => { + if (userSearchState.type === "user") { + const u = userSearchState.data; + const addable = + members.findIndex((m) => m.username === u.username) === -1; + return ( + <> + {!addable ? ( + <p>{t("timeline.member.alreadyMember")}</p> + ) : null} + <Container className="mb-3"> + <Row> + <Col className="col-auto"> + <BlobImage + blob={userSearchAvatar} + className="avatar small" + /> + </Col> + <Col> + <Row>{u.nickname}</Row> + <Row> + <small>{"@" + u.username}</small> + </Row> + </Col> + <Button + color="primary" + className="align-self-center" + disabled={!addable} + onClick={() => { + void edit.onAddUser(u).then((_) => { + setUserSearchText(""); + setUserSearchState({ type: "init" }); + }); + }} + > + {t("timeline.member.add")} + </Button> + </Row> + </Container> + </> + ); + } else if (userSearchState.type === "error") { + return ( + <p className="text-danger">{t(userSearchState.data)}</p> + ); + } + })()} + </> + ); + } else { + return null; + } + })()} + </Container> + ); +}; + +export default TimelineMember; + +export interface TimelineMemberDialogProps extends TimelineMemberProps { + open: boolean; + onClose: () => void; +} + +export const TimelineMemberDialog: React.FC<TimelineMemberDialogProps> = ( + props +) => { + return ( + <Modal isOpen={props.open} toggle={props.onClose}> + <TimelineMember {...props} /> + </Modal> + ); +}; diff --git a/Timeline/ClientApp/src/app/timeline/TimelinePage.tsx b/Timeline/ClientApp/src/app/timeline/TimelinePage.tsx index 7d0a8807..0771b40e 100644 --- a/Timeline/ClientApp/src/app/timeline/TimelinePage.tsx +++ b/Timeline/ClientApp/src/app/timeline/TimelinePage.tsx @@ -1,36 +1,36 @@ -import React from 'react';
-import { useParams } from 'react-router';
-
-import TimelinePageUI from './TimelinePageUI';
-import TimelinePageTemplate from '../timeline/TimelinePageTemplate';
-import { OrdinaryTimelineManageItem } from './TimelineInfoCard';
-import TimelineDeleteDialog from './TimelineDeleteDialog';
-
-const TimelinePage: React.FC = (_) => {
- const { name } = useParams<{ name: string }>();
-
- const [dialog, setDialog] = React.useState<OrdinaryTimelineManageItem | null>(
- null
- );
-
- let dialogElement: React.ReactElement | undefined;
- if (dialog === 'delete') {
- dialogElement = (
- <TimelineDeleteDialog open close={() => setDialog(null)} name={name} />
- );
- }
-
- return (
- <>
- <TimelinePageTemplate
- name={name}
- UiComponent={TimelinePageUI}
- onManage={(item) => setDialog(item)}
- notFoundI18nKey="timeline.timelineNotExist"
- />
- {dialogElement}
- </>
- );
-};
-
-export default TimelinePage;
+import React from "react"; +import { useParams } from "react-router"; + +import TimelinePageUI from "./TimelinePageUI"; +import TimelinePageTemplate from "../timeline/TimelinePageTemplate"; +import { OrdinaryTimelineManageItem } from "./TimelineInfoCard"; +import TimelineDeleteDialog from "./TimelineDeleteDialog"; + +const TimelinePage: React.FC = (_) => { + const { name } = useParams<{ name: string }>(); + + const [dialog, setDialog] = React.useState<OrdinaryTimelineManageItem | null>( + null + ); + + let dialogElement: React.ReactElement | undefined; + if (dialog === "delete") { + dialogElement = ( + <TimelineDeleteDialog open close={() => setDialog(null)} name={name} /> + ); + } + + return ( + <> + <TimelinePageTemplate + name={name} + UiComponent={TimelinePageUI} + onManage={(item) => setDialog(item)} + notFoundI18nKey="timeline.timelineNotExist" + /> + {dialogElement} + </> + ); +}; + +export default TimelinePage; diff --git a/Timeline/ClientApp/src/app/timeline/TimelinePageTemplate.tsx b/Timeline/ClientApp/src/app/timeline/TimelinePageTemplate.tsx index 89101f8f..be96a09e 100644 --- a/Timeline/ClientApp/src/app/timeline/TimelinePageTemplate.tsx +++ b/Timeline/ClientApp/src/app/timeline/TimelinePageTemplate.tsx @@ -1,191 +1,191 @@ -import React from 'react';
-import { useTranslation } from 'react-i18next';
-import { of } from 'rxjs';
-import { catchError } from 'rxjs/operators';
-
-import { ExcludeKey } from '../utilities/type';
-import { pushAlert } from '../common/alert-service';
-import { useUser, userInfoService, UserNotExistError } from '../data/user';
-import {
- timelineService,
- usePostList,
- useTimelineInfo,
-} from '../data/timeline';
-
-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;
- onManage: (item: TManageItem) => void;
- UiComponent: React.ComponentType<
- ExcludeKey<TimelinePageTemplateUIProps<TManageItem>, 'CardComponent'>
- >;
- dataVersion?: number;
- notFoundI18nKey: string;
-}
-
-export default function TimelinePageTemplate<TManageItem>(
- props: TimelinePageTemplateProps<TManageItem>
-): React.ReactElement | null {
- const { t } = useTranslation();
-
- const { name } = props;
-
- const service = timelineService;
-
- const user = useUser();
-
- const [dialog, setDialog] = React.useState<null | 'property' | 'member'>(
- null
- );
-
- const timelineState = useTimelineInfo(name);
-
- const timeline = timelineState?.timeline;
-
- const postListState = usePostList(name);
-
- const error: string | undefined = (() => {
- if (timelineState != null) {
- const { type, timeline } = timelineState;
- if (type === 'offline' && timeline == null) return 'Network Error';
- if (type === 'synced' && timeline == null)
- return t(props.notFoundI18nKey);
- }
- return undefined;
- })();
-
- const closeDialog = React.useCallback((): void => {
- setDialog(null);
- }, []);
-
- let dialogElement: React.ReactElement | undefined;
-
- if (dialog === 'property') {
- if (timeline == null) {
- throw new UiLogicError(
- 'Timeline is null but attempt to open change property dialog.'
- );
- }
-
- dialogElement = (
- <TimelinePropertyChangeDialog
- open
- close={closeDialog}
- oldInfo={{
- visibility: timeline.visibility,
- description: timeline.description,
- }}
- onProcess={(req) => {
- return service.changeTimelineProperty(name, req).toPromise().then();
- }}
- />
- );
- } else if (dialog === 'member') {
- if (timeline == null) {
- throw new UiLogicError(
- 'Timeline is null but attempt to open change property dialog.'
- );
- }
-
- dialogElement = (
- <TimelineMemberDialog
- open
- onClose={closeDialog}
- members={[timeline.owner, ...timeline.members]}
- edit={
- service.hasManagePermission(user, timeline)
- ? {
- onCheckUser: (u) => {
- return userInfoService
- .getUserInfo(u)
- .pipe(
- catchError((e) => {
- if (e instanceof UserNotExistError) {
- return of(null);
- } else {
- throw e;
- }
- })
- )
- .toPromise();
- },
- onAddUser: (u) => {
- return service.addMember(name, u.username).toPromise().then();
- },
- onRemoveUser: (u) => {
- service.removeMember(name, u);
- },
- }
- : null
- }
- />
- );
- }
-
- const { UiComponent } = props;
-
- const onDelete: TimelineDeleteCallback = React.useCallback(
- (index, id) => {
- service.deletePost(name, id).subscribe(null, () => {
- pushAlert({
- type: 'danger',
- message: t('timeline.deletePostFailed'),
- });
- });
- },
- [service, name, t]
- );
-
- const onPost: TimelinePostSendCallback = React.useCallback(
- (req) => {
- return service.createPost(name, req).toPromise().then();
- },
- [service, name]
- );
-
- const onManageProp = props.onManage;
-
- const onManage = React.useCallback(
- (item: 'property' | TManageItem) => {
- if (item === 'property') {
- setDialog(item);
- } else {
- onManageProp(item);
- }
- },
- [onManageProp]
- );
-
- const onMember = React.useCallback(() => {
- setDialog('member');
- }, []);
-
- return (
- <>
- <UiComponent
- error={error}
- timeline={timeline ?? undefined}
- postListState={postListState}
- onDelete={onDelete}
- onPost={
- timeline != null && service.hasPostPermission(user, timeline)
- ? onPost
- : undefined
- }
- onManage={
- timeline != null && service.hasManagePermission(user, timeline)
- ? onManage
- : undefined
- }
- onMember={onMember}
- />
- {dialogElement}
- </>
- );
-}
+import React from "react"; +import { useTranslation } from "react-i18next"; +import { of } from "rxjs"; +import { catchError } from "rxjs/operators"; + +import { ExcludeKey } from "../utilities/type"; +import { pushAlert } from "../common/alert-service"; +import { useUser, userInfoService, UserNotExistError } from "../data/user"; +import { + timelineService, + usePostList, + useTimelineInfo, +} from "../data/timeline"; + +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; + onManage: (item: TManageItem) => void; + UiComponent: React.ComponentType< + ExcludeKey<TimelinePageTemplateUIProps<TManageItem>, "CardComponent"> + >; + dataVersion?: number; + notFoundI18nKey: string; +} + +export default function TimelinePageTemplate<TManageItem>( + props: TimelinePageTemplateProps<TManageItem> +): React.ReactElement | null { + const { t } = useTranslation(); + + const { name } = props; + + const service = timelineService; + + const user = useUser(); + + const [dialog, setDialog] = React.useState<null | "property" | "member">( + null + ); + + const timelineState = useTimelineInfo(name); + + const timeline = timelineState?.timeline; + + const postListState = usePostList(name); + + const error: string | undefined = (() => { + if (timelineState != null) { + const { type, timeline } = timelineState; + if (type === "offline" && timeline == null) return "Network Error"; + if (type === "synced" && timeline == null) + return t(props.notFoundI18nKey); + } + return undefined; + })(); + + const closeDialog = React.useCallback((): void => { + setDialog(null); + }, []); + + let dialogElement: React.ReactElement | undefined; + + if (dialog === "property") { + if (timeline == null) { + throw new UiLogicError( + "Timeline is null but attempt to open change property dialog." + ); + } + + dialogElement = ( + <TimelinePropertyChangeDialog + open + close={closeDialog} + oldInfo={{ + visibility: timeline.visibility, + description: timeline.description, + }} + onProcess={(req) => { + return service.changeTimelineProperty(name, req).toPromise().then(); + }} + /> + ); + } else if (dialog === "member") { + if (timeline == null) { + throw new UiLogicError( + "Timeline is null but attempt to open change property dialog." + ); + } + + dialogElement = ( + <TimelineMemberDialog + open + onClose={closeDialog} + members={[timeline.owner, ...timeline.members]} + edit={ + service.hasManagePermission(user, timeline) + ? { + onCheckUser: (u) => { + return userInfoService + .getUserInfo(u) + .pipe( + catchError((e) => { + if (e instanceof UserNotExistError) { + return of(null); + } else { + throw e; + } + }) + ) + .toPromise(); + }, + onAddUser: (u) => { + return service.addMember(name, u.username).toPromise().then(); + }, + onRemoveUser: (u) => { + service.removeMember(name, u); + }, + } + : null + } + /> + ); + } + + const { UiComponent } = props; + + const onDelete: TimelineDeleteCallback = React.useCallback( + (index, id) => { + service.deletePost(name, id).subscribe(null, () => { + pushAlert({ + type: "danger", + message: t("timeline.deletePostFailed"), + }); + }); + }, + [service, name, t] + ); + + const onPost: TimelinePostSendCallback = React.useCallback( + (req) => { + return service.createPost(name, req).toPromise().then(); + }, + [service, name] + ); + + const onManageProp = props.onManage; + + const onManage = React.useCallback( + (item: "property" | TManageItem) => { + if (item === "property") { + setDialog(item); + } else { + onManageProp(item); + } + }, + [onManageProp] + ); + + const onMember = React.useCallback(() => { + setDialog("member"); + }, []); + + return ( + <> + <UiComponent + error={error} + timeline={timeline ?? undefined} + postListState={postListState} + onDelete={onDelete} + onPost={ + timeline != null && service.hasPostPermission(user, timeline) + ? onPost + : undefined + } + onManage={ + timeline != null && service.hasManagePermission(user, timeline) + ? onManage + : undefined + } + onMember={onMember} + /> + {dialogElement} + </> + ); +} diff --git a/Timeline/ClientApp/src/app/timeline/TimelinePageTemplateUI.tsx b/Timeline/ClientApp/src/app/timeline/TimelinePageTemplateUI.tsx index 18b3323d..2066ceb1 100644 --- a/Timeline/ClientApp/src/app/timeline/TimelinePageTemplateUI.tsx +++ b/Timeline/ClientApp/src/app/timeline/TimelinePageTemplateUI.tsx @@ -1,325 +1,325 @@ -import React, { CSSProperties } from 'react';
-import { Spinner } from 'reactstrap';
-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';
-
-import { getAlertHost } from '../common/alert-service';
-import { useEventEmiiter, UiLogicError } from '../common';
-import {
- TimelineInfo,
- TimelinePostsWithSyncState,
- timelineService,
-} from '../data/timeline';
-import { userService } from '../data/user';
-
-import Timeline, {
- TimelinePostInfoEx,
- TimelineDeleteCallback,
-} from './Timeline';
-import AppBar from '../common/AppBar';
-import TimelinePostEdit, { TimelinePostSendCallback } from './TimelinePostEdit';
-
-type TimelinePostSyncState = 'syncing' | 'synced' | 'offline';
-
-const TimelinePostSyncStateBadge: React.FC<{
- state: TimelinePostSyncState;
- style?: CSSProperties;
- className?: string;
-}> = ({ state, style, className }) => {
- const { t } = useTranslation();
-
- return (
- <div style={style} className={clsx('timeline-sync-state-badge', className)}>
- {(() => {
- switch (state) {
- case 'syncing': {
- return (
- <>
- <span className="timeline-sync-state-badge-pin bg-warning" />
- <span className="text-warning">
- {t('timeline.postSyncState.syncing')}
- </span>
- </>
- );
- }
- case 'synced': {
- return (
- <>
- <span className="timeline-sync-state-badge-pin bg-success" />
- <span className="text-success">
- {t('timeline.postSyncState.synced')}
- </span>
- </>
- );
- }
- case 'offline': {
- return (
- <>
- <span className="timeline-sync-state-badge-pin bg-danger" />
- <span className="text-danger">
- {t('timeline.postSyncState.offline')}
- </span>
- </>
- );
- }
- default:
- throw new UiLogicError('Unknown sync state.');
- }
- })()}
- </div>
- );
-};
-
-export interface TimelineCardComponentProps<TManageItems> {
- timeline: TimelineInfo;
- onManage?: (item: TManageItems | 'property') => void;
- onMember: () => void;
- className?: string;
- onHeight?: (height: number) => void;
-}
-
-export interface TimelinePageTemplateUIProps<TManageItems> {
- avatarKey?: string | number;
- timeline?: TimelineInfo;
- postListState?: TimelinePostsWithSyncState;
- CardComponent: React.ComponentType<TimelineCardComponentProps<TManageItems>>;
- onMember: () => void;
- onManage?: (item: TManageItems | 'property') => void;
- onPost?: TimelinePostSendCallback;
- onDelete: TimelineDeleteCallback;
- error?: string;
-}
-
-export default function TimelinePageTemplateUI<TManageItems>(
- props: TimelinePageTemplateUIProps<TManageItems>
-): React.ReactElement | null {
- const { timeline, postListState } = props;
-
- const { t } = useTranslation();
-
- const bottomSpaceRef = React.useRef<HTMLDivElement | null>(null);
-
- const onPostEditHeightChange = React.useCallback((height: number): void => {
- const { current: bottomSpaceDiv } = bottomSpaceRef;
- if (bottomSpaceDiv != null) {
- bottomSpaceDiv.style.height = `${height}px`;
- }
- if (height === 0) {
- const alertHost = getAlertHost();
- if (alertHost != null) {
- alertHost.style.removeProperty('margin-bottom');
- }
- } else {
- const alertHost = getAlertHost();
- if (alertHost != null) {
- alertHost.style.marginBottom = `${height}px`;
- }
- }
- }, []);
-
- const timelineRef = React.useRef<HTMLDivElement | null>(null);
-
- const [getResizeEvent, triggerResizeEvent] = useEventEmiiter();
-
- React.useEffect(() => {
- const { current: timelineElement } = timelineRef;
- if (timelineElement != null) {
- let loadingScrollToBottom = true;
- let pinBottom = false;
-
- const isAtBottom = (): boolean =>
- window.innerHeight + window.scrollY + 10 >= document.body.scrollHeight;
-
- const disableLoadingScrollToBottom = (): void => {
- loadingScrollToBottom = false;
- if (isAtBottom()) pinBottom = true;
- };
-
- const checkAndScrollToBottom = (): void => {
- if (loadingScrollToBottom || pinBottom) {
- window.scrollTo(0, document.body.scrollHeight);
- }
- };
-
- const subscriptions = [
- fromEvent(timelineElement, 'wheel').subscribe(
- disableLoadingScrollToBottom
- ),
- fromEvent(timelineElement, 'pointerdown').subscribe(
- disableLoadingScrollToBottom
- ),
- fromEvent(timelineElement, 'keydown').subscribe(
- disableLoadingScrollToBottom
- ),
- fromEvent(window, 'scroll').subscribe(() => {
- if (loadingScrollToBottom) return;
-
- if (isAtBottom()) {
- pinBottom = true;
- } else {
- pinBottom = false;
- }
- }),
- fromEvent(window, 'resize').subscribe(checkAndScrollToBottom),
- getResizeEvent().subscribe(checkAndScrollToBottom),
- ];
-
- return () => {
- subscriptions.forEach((s) => s.unsubscribe());
- };
- }
- }, [getResizeEvent, triggerResizeEvent, timeline, postListState]);
-
- const [cardHeight, setCardHeight] = React.useState<number>(0);
-
- const genCardCollapseLocalStorageKey = (uniqueId: string): string =>
- `timeline.${uniqueId}.cardCollapse`;
-
- const cardCollapseLocalStorageKey =
- timeline != null ? genCardCollapseLocalStorageKey(timeline.uniqueId) : null;
-
- const [infoCardCollapse, setInfoCardCollapse] = React.useState<boolean>(true);
- React.useEffect(() => {
- if (cardCollapseLocalStorageKey != null) {
- const savedCollapse =
- window.localStorage.getItem(cardCollapseLocalStorageKey) === 'true';
- setInfoCardCollapse(savedCollapse);
- }
- }, [cardCollapseLocalStorageKey]);
-
- let body: React.ReactElement;
-
- if (props.error != null) {
- body = <p className="text-danger">{t(props.error)}</p>;
- } else {
- if (timeline != null) {
- let timelineBody: React.ReactElement;
- if (postListState != null) {
- if (postListState.type === 'notexist') {
- throw new UiLogicError(
- 'Timeline is not null but post list state is notexist.'
- );
- }
- if (postListState.type === 'forbid') {
- timelineBody = (
- <p className="text-danger">{t('timeline.messageCantSee')}</p>
- );
- } else {
- const posts: TimelinePostInfoEx[] = postListState.posts.map(
- (post) => ({
- ...post,
- deletable: timelineService.hasModifyPostPermission(
- userService.currentUser,
- timeline,
- post
- ),
- })
- );
-
- const topHeight: string = infoCardCollapse
- ? 'calc(68px + 1.5em)'
- : `${cardHeight + 60}px`;
-
- const syncState: TimelinePostSyncState = postListState.syncing
- ? 'syncing'
- : postListState.type === 'synced'
- ? 'synced'
- : 'offline';
-
- timelineBody = (
- <div>
- <TimelinePostSyncStateBadge
- style={{ top: topHeight }}
- state={syncState}
- />
- <Timeline
- containerRef={timelineRef}
- posts={posts}
- onDelete={props.onDelete}
- onResize={triggerResizeEvent}
- />
- </div>
- );
- if (props.onPost != null) {
- timelineBody = (
- <>
- {timelineBody}
- <div ref={bottomSpaceRef} className="flex-fix-length" />
- <TimelinePostEdit
- onPost={props.onPost}
- onHeightChange={onPostEditHeightChange}
- timelineUniqueId={timeline.uniqueId}
- />
- </>
- );
- }
- }
- } else {
- timelineBody = (
- <div className="full-viewport-center-child">
- <Spinner color="primary" type="grow" />
- </div>
- );
- }
- const { CardComponent } = props;
-
- body = (
- <>
- <div
- className="fixed-top mt-appbar info-card-container"
- data-collapse={infoCardCollapse ? 'true' : 'false'}
- >
- <Svg
- src={
- infoCardCollapse
- ? arrowsAngleExpandIcon
- : arrowsAngleContractIcon
- }
- onClick={() => {
- const newState = !infoCardCollapse;
- setInfoCardCollapse(newState);
- window.localStorage.setItem(
- genCardCollapseLocalStorageKey(timeline.uniqueId),
- newState.toString()
- );
- }}
- className="float-right m-1 info-card-collapse-button text-primary icon-button"
- />
- <CardComponent
- timeline={timeline}
- onManage={props.onManage}
- onMember={props.onMember}
- onHeight={setCardHeight}
- className="info-card-content"
- />
- </div>
- {timelineBody}
- </>
- );
- } else {
- body = (
- <div className="full-viewport-center-child">
- <Spinner color="primary" type="grow" />
- </div>
- );
- }
- }
-
- return (
- <>
- <AppBar />
- <div>
- <div
- style={{ height: 56 + cardHeight }}
- className="timeline-page-top-space flex-fix-length"
- />
- {body}
- </div>
- </>
- );
-}
+import React, { CSSProperties } from "react"; +import { Spinner } from "reactstrap"; +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"; + +import { getAlertHost } from "../common/alert-service"; +import { useEventEmiiter, UiLogicError } from "../common"; +import { + TimelineInfo, + TimelinePostsWithSyncState, + timelineService, +} from "../data/timeline"; +import { userService } from "../data/user"; + +import Timeline, { + TimelinePostInfoEx, + TimelineDeleteCallback, +} from "./Timeline"; +import AppBar from "../common/AppBar"; +import TimelinePostEdit, { TimelinePostSendCallback } from "./TimelinePostEdit"; + +type TimelinePostSyncState = "syncing" | "synced" | "offline"; + +const TimelinePostSyncStateBadge: React.FC<{ + state: TimelinePostSyncState; + style?: CSSProperties; + className?: string; +}> = ({ state, style, className }) => { + const { t } = useTranslation(); + + return ( + <div style={style} className={clsx("timeline-sync-state-badge", className)}> + {(() => { + switch (state) { + case "syncing": { + return ( + <> + <span className="timeline-sync-state-badge-pin bg-warning" /> + <span className="text-warning"> + {t("timeline.postSyncState.syncing")} + </span> + </> + ); + } + case "synced": { + return ( + <> + <span className="timeline-sync-state-badge-pin bg-success" /> + <span className="text-success"> + {t("timeline.postSyncState.synced")} + </span> + </> + ); + } + case "offline": { + return ( + <> + <span className="timeline-sync-state-badge-pin bg-danger" /> + <span className="text-danger"> + {t("timeline.postSyncState.offline")} + </span> + </> + ); + } + default: + throw new UiLogicError("Unknown sync state."); + } + })()} + </div> + ); +}; + +export interface TimelineCardComponentProps<TManageItems> { + timeline: TimelineInfo; + onManage?: (item: TManageItems | "property") => void; + onMember: () => void; + className?: string; + onHeight?: (height: number) => void; +} + +export interface TimelinePageTemplateUIProps<TManageItems> { + avatarKey?: string | number; + timeline?: TimelineInfo; + postListState?: TimelinePostsWithSyncState; + CardComponent: React.ComponentType<TimelineCardComponentProps<TManageItems>>; + onMember: () => void; + onManage?: (item: TManageItems | "property") => void; + onPost?: TimelinePostSendCallback; + onDelete: TimelineDeleteCallback; + error?: string; +} + +export default function TimelinePageTemplateUI<TManageItems>( + props: TimelinePageTemplateUIProps<TManageItems> +): React.ReactElement | null { + const { timeline, postListState } = props; + + const { t } = useTranslation(); + + const bottomSpaceRef = React.useRef<HTMLDivElement | null>(null); + + const onPostEditHeightChange = React.useCallback((height: number): void => { + const { current: bottomSpaceDiv } = bottomSpaceRef; + if (bottomSpaceDiv != null) { + bottomSpaceDiv.style.height = `${height}px`; + } + if (height === 0) { + const alertHost = getAlertHost(); + if (alertHost != null) { + alertHost.style.removeProperty("margin-bottom"); + } + } else { + const alertHost = getAlertHost(); + if (alertHost != null) { + alertHost.style.marginBottom = `${height}px`; + } + } + }, []); + + const timelineRef = React.useRef<HTMLDivElement | null>(null); + + const [getResizeEvent, triggerResizeEvent] = useEventEmiiter(); + + React.useEffect(() => { + const { current: timelineElement } = timelineRef; + if (timelineElement != null) { + let loadingScrollToBottom = true; + let pinBottom = false; + + const isAtBottom = (): boolean => + window.innerHeight + window.scrollY + 10 >= document.body.scrollHeight; + + const disableLoadingScrollToBottom = (): void => { + loadingScrollToBottom = false; + if (isAtBottom()) pinBottom = true; + }; + + const checkAndScrollToBottom = (): void => { + if (loadingScrollToBottom || pinBottom) { + window.scrollTo(0, document.body.scrollHeight); + } + }; + + const subscriptions = [ + fromEvent(timelineElement, "wheel").subscribe( + disableLoadingScrollToBottom + ), + fromEvent(timelineElement, "pointerdown").subscribe( + disableLoadingScrollToBottom + ), + fromEvent(timelineElement, "keydown").subscribe( + disableLoadingScrollToBottom + ), + fromEvent(window, "scroll").subscribe(() => { + if (loadingScrollToBottom) return; + + if (isAtBottom()) { + pinBottom = true; + } else { + pinBottom = false; + } + }), + fromEvent(window, "resize").subscribe(checkAndScrollToBottom), + getResizeEvent().subscribe(checkAndScrollToBottom), + ]; + + return () => { + subscriptions.forEach((s) => s.unsubscribe()); + }; + } + }, [getResizeEvent, triggerResizeEvent, timeline, postListState]); + + const [cardHeight, setCardHeight] = React.useState<number>(0); + + const genCardCollapseLocalStorageKey = (uniqueId: string): string => + `timeline.${uniqueId}.cardCollapse`; + + const cardCollapseLocalStorageKey = + timeline != null ? genCardCollapseLocalStorageKey(timeline.uniqueId) : null; + + const [infoCardCollapse, setInfoCardCollapse] = React.useState<boolean>(true); + React.useEffect(() => { + if (cardCollapseLocalStorageKey != null) { + const savedCollapse = + window.localStorage.getItem(cardCollapseLocalStorageKey) === "true"; + setInfoCardCollapse(savedCollapse); + } + }, [cardCollapseLocalStorageKey]); + + let body: React.ReactElement; + + if (props.error != null) { + body = <p className="text-danger">{t(props.error)}</p>; + } else { + if (timeline != null) { + let timelineBody: React.ReactElement; + if (postListState != null) { + if (postListState.type === "notexist") { + throw new UiLogicError( + "Timeline is not null but post list state is notexist." + ); + } + if (postListState.type === "forbid") { + timelineBody = ( + <p className="text-danger">{t("timeline.messageCantSee")}</p> + ); + } else { + const posts: TimelinePostInfoEx[] = postListState.posts.map( + (post) => ({ + ...post, + deletable: timelineService.hasModifyPostPermission( + userService.currentUser, + timeline, + post + ), + }) + ); + + const topHeight: string = infoCardCollapse + ? "calc(68px + 1.5em)" + : `${cardHeight + 60}px`; + + const syncState: TimelinePostSyncState = postListState.syncing + ? "syncing" + : postListState.type === "synced" + ? "synced" + : "offline"; + + timelineBody = ( + <div> + <TimelinePostSyncStateBadge + style={{ top: topHeight }} + state={syncState} + /> + <Timeline + containerRef={timelineRef} + posts={posts} + onDelete={props.onDelete} + onResize={triggerResizeEvent} + /> + </div> + ); + if (props.onPost != null) { + timelineBody = ( + <> + {timelineBody} + <div ref={bottomSpaceRef} className="flex-fix-length" /> + <TimelinePostEdit + onPost={props.onPost} + onHeightChange={onPostEditHeightChange} + timelineUniqueId={timeline.uniqueId} + /> + </> + ); + } + } + } else { + timelineBody = ( + <div className="full-viewport-center-child"> + <Spinner color="primary" type="grow" /> + </div> + ); + } + const { CardComponent } = props; + + body = ( + <> + <div + className="fixed-top mt-appbar info-card-container" + data-collapse={infoCardCollapse ? "true" : "false"} + > + <Svg + src={ + infoCardCollapse + ? arrowsAngleExpandIcon + : arrowsAngleContractIcon + } + onClick={() => { + const newState = !infoCardCollapse; + setInfoCardCollapse(newState); + window.localStorage.setItem( + genCardCollapseLocalStorageKey(timeline.uniqueId), + newState.toString() + ); + }} + className="float-right m-1 info-card-collapse-button text-primary icon-button" + /> + <CardComponent + timeline={timeline} + onManage={props.onManage} + onMember={props.onMember} + onHeight={setCardHeight} + className="info-card-content" + /> + </div> + {timelineBody} + </> + ); + } else { + body = ( + <div className="full-viewport-center-child"> + <Spinner color="primary" type="grow" /> + </div> + ); + } + } + + return ( + <> + <AppBar /> + <div> + <div + style={{ height: 56 + cardHeight }} + className="timeline-page-top-space flex-fix-length" + /> + {body} + </div> + </> + ); +} diff --git a/Timeline/ClientApp/src/app/timeline/TimelinePageUI.tsx b/Timeline/ClientApp/src/app/timeline/TimelinePageUI.tsx index 88cc2226..63751eeb 100644 --- a/Timeline/ClientApp/src/app/timeline/TimelinePageUI.tsx +++ b/Timeline/ClientApp/src/app/timeline/TimelinePageUI.tsx @@ -1,21 +1,21 @@ -import React from 'react';
-
-import { ExcludeKey } from '../utilities/type';
-
-import TimelinePageTemplateUI, {
- TimelinePageTemplateUIProps,
-} from './TimelinePageTemplateUI';
-import TimelineInfoCard, {
- OrdinaryTimelineManageItem,
-} from './TimelineInfoCard';
-
-export type TimelinePageUIProps = ExcludeKey<
- TimelinePageTemplateUIProps<OrdinaryTimelineManageItem>,
- 'CardComponent'
->;
-
-const TimelinePageUI: React.FC<TimelinePageUIProps> = (props) => {
- return <TimelinePageTemplateUI {...props} CardComponent={TimelineInfoCard} />;
-};
-
-export default TimelinePageUI;
+import React from "react"; + +import { ExcludeKey } from "../utilities/type"; + +import TimelinePageTemplateUI, { + TimelinePageTemplateUIProps, +} from "./TimelinePageTemplateUI"; +import TimelineInfoCard, { + OrdinaryTimelineManageItem, +} from "./TimelineInfoCard"; + +export type TimelinePageUIProps = ExcludeKey< + TimelinePageTemplateUIProps<OrdinaryTimelineManageItem>, + "CardComponent" +>; + +const TimelinePageUI: React.FC<TimelinePageUIProps> = (props) => { + return <TimelinePageTemplateUI {...props} CardComponent={TimelineInfoCard} />; +}; + +export default TimelinePageUI; diff --git a/Timeline/ClientApp/src/app/timeline/TimelinePostEdit.tsx b/Timeline/ClientApp/src/app/timeline/TimelinePostEdit.tsx index d4d626ae..151df40a 100644 --- a/Timeline/ClientApp/src/app/timeline/TimelinePostEdit.tsx +++ b/Timeline/ClientApp/src/app/timeline/TimelinePostEdit.tsx @@ -1,234 +1,234 @@ -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';
-
-interface TimelinePostEditImageProps {
- onSelect: (blob: Blob | null) => void;
-}
-
-const TimelinePostEditImage: React.FC<TimelinePostEditImageProps> = (props) => {
- const { onSelect } = props;
- const { t } = useTranslation();
-
- const [file, setFile] = React.useState<File | null>(null);
- const [fileUrl, setFileUrl] = React.useState<string | null>(null);
- const [error, setError] = React.useState<string | null>(null);
-
- React.useEffect(() => {
- if (file != null) {
- const url = URL.createObjectURL(file);
- setFileUrl(url);
- return () => {
- URL.revokeObjectURL(url);
- };
- }
- }, [file]);
-
- const onInputChange: React.ChangeEventHandler<HTMLInputElement> = React.useCallback(
- (e) => {
- const files = e.target.files;
- if (files == null || files.length === 0) {
- setFile(null);
- setFileUrl(null);
- } else {
- setFile(files[0]);
- }
- onSelect(null);
- setError(null);
- },
- [onSelect]
- );
-
- const onImgLoad = React.useCallback(() => {
- onSelect(file);
- }, [onSelect, file]);
-
- const onImgError = React.useCallback(() => {
- setError('loadImageError');
- }, []);
-
- return (
- <>
- <FileInput
- labelText={t('chooseImage')}
- onChange={onInputChange}
- accept="image/*"
- className="mx-3 my-1"
- />
- {fileUrl && error == null && (
- <img
- src={fileUrl}
- className="timeline-post-edit-image"
- onLoad={onImgLoad}
- onError={onImgError}
- />
- )}
- {error != null && <div className="text-danger">{t(error)}</div>}
- </>
- );
-};
-
-export type TimelinePostSendCallback = (
- content: TimelineCreatePostRequest
-) => Promise<void>;
-
-export interface TimelinePostEditProps {
- className?: string;
- onPost: TimelinePostSendCallback;
- onHeightChange?: (height: number) => void;
- timelineUniqueId: string;
-}
-
-const TimelinePostEdit: React.FC<TimelinePostEditProps> = (props) => {
- const { onPost } = props;
-
- const { t } = useTranslation();
-
- const [state, setState] = React.useState<'input' | 'process'>('input');
- const [kind, setKind] = React.useState<'text' | 'image'>('text');
- const [text, setText] = React.useState<string>('');
- const [imageBlob, setImageBlob] = React.useState<Blob | null>(null);
-
- const draftLocalStorageKey = `timeline.${props.timelineUniqueId}.postDraft`;
-
- React.useEffect(() => {
- setText(window.localStorage.getItem(draftLocalStorageKey) ?? '');
- }, [draftLocalStorageKey]);
-
- const canSend = kind === 'text' || (kind === 'image' && imageBlob != null);
-
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const containerRef = React.useRef<HTMLDivElement>(null!);
-
- const notifyHeightChange = (): void => {
- if (props.onHeightChange) {
- props.onHeightChange(containerRef.current.clientHeight);
- }
- };
-
- React.useEffect(() => {
- if (props.onHeightChange) {
- props.onHeightChange(containerRef.current.clientHeight);
- }
- return () => {
- if (props.onHeightChange) {
- props.onHeightChange(0);
- }
- };
- });
-
- const toggleKind = React.useCallback(() => {
- setKind((oldKind) => (oldKind === 'text' ? 'image' : 'text'));
- setImageBlob(null);
- }, []);
-
- const onSend = React.useCallback(() => {
- setState('process');
-
- const req: TimelineCreatePostRequest = (() => {
- switch (kind) {
- case 'text':
- return {
- content: {
- type: 'text',
- text: text,
- },
- } as TimelineCreatePostRequest;
- case 'image':
- if (imageBlob == null) {
- throw new UiLogicError(
- 'Content type is image but image blob is null.'
- );
- }
- return {
- content: {
- type: 'image',
- data: imageBlob,
- },
- } as TimelineCreatePostRequest;
- default:
- throw new UiLogicError('Unknown content type.');
- }
- })();
-
- onPost(req).then(
- (_) => {
- if (kind === 'text') {
- setText('');
- window.localStorage.removeItem(draftLocalStorageKey);
- }
- setState('input');
- setKind('text');
- },
- (_) => {
- pushAlert({
- type: 'danger',
- message: t('timeline.sendPostFailed'),
- });
- setState('input');
- }
- );
- }, [onPost, kind, text, imageBlob, t, draftLocalStorageKey]);
-
- const onImageSelect = React.useCallback((blob: Blob | null) => {
- setImageBlob(blob);
- }, []);
-
- return (
- <div ref={containerRef} className="container-fluid fixed-bottom bg-light">
- <Row>
- <Col className="px-1 py-1">
- {kind === 'text' ? (
- <textarea
- className="w-100 h-100 timeline-post-edit"
- value={text}
- disabled={state === 'process'}
- onChange={(event: React.ChangeEvent<HTMLTextAreaElement>) => {
- const value = event.currentTarget.value;
- setText(value);
- window.localStorage.setItem(draftLocalStorageKey, value);
- }}
- />
- ) : (
- <TimelinePostEditImage onSelect={onImageSelect} />
- )}
- </Col>
- <Col sm="col-auto align-self-end m-1">
- {(() => {
- if (state === 'input') {
- return (
- <>
- <div className="d-block text-center mt-1 mb-2">
- <Svg
- onLoad={notifyHeightChange}
- src={kind === 'text' ? imageIcon : textIcon}
- className="icon-button"
- onClick={toggleKind}
- />
- </div>
- <Button color="primary" onClick={onSend} disabled={!canSend}>
- {t('timeline.send')}
- </Button>
- </>
- );
- } else {
- return <Spinner />;
- }
- })()}
- </Col>
- </Row>
- </div>
- );
-};
-
-export default TimelinePostEdit;
+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"; + +interface TimelinePostEditImageProps { + onSelect: (blob: Blob | null) => void; +} + +const TimelinePostEditImage: React.FC<TimelinePostEditImageProps> = (props) => { + const { onSelect } = props; + const { t } = useTranslation(); + + const [file, setFile] = React.useState<File | null>(null); + const [fileUrl, setFileUrl] = React.useState<string | null>(null); + const [error, setError] = React.useState<string | null>(null); + + React.useEffect(() => { + if (file != null) { + const url = URL.createObjectURL(file); + setFileUrl(url); + return () => { + URL.revokeObjectURL(url); + }; + } + }, [file]); + + const onInputChange: React.ChangeEventHandler<HTMLInputElement> = React.useCallback( + (e) => { + const files = e.target.files; + if (files == null || files.length === 0) { + setFile(null); + setFileUrl(null); + } else { + setFile(files[0]); + } + onSelect(null); + setError(null); + }, + [onSelect] + ); + + const onImgLoad = React.useCallback(() => { + onSelect(file); + }, [onSelect, file]); + + const onImgError = React.useCallback(() => { + setError("loadImageError"); + }, []); + + return ( + <> + <FileInput + labelText={t("chooseImage")} + onChange={onInputChange} + accept="image/*" + className="mx-3 my-1" + /> + {fileUrl && error == null && ( + <img + src={fileUrl} + className="timeline-post-edit-image" + onLoad={onImgLoad} + onError={onImgError} + /> + )} + {error != null && <div className="text-danger">{t(error)}</div>} + </> + ); +}; + +export type TimelinePostSendCallback = ( + content: TimelineCreatePostRequest +) => Promise<void>; + +export interface TimelinePostEditProps { + className?: string; + onPost: TimelinePostSendCallback; + onHeightChange?: (height: number) => void; + timelineUniqueId: string; +} + +const TimelinePostEdit: React.FC<TimelinePostEditProps> = (props) => { + const { onPost } = props; + + const { t } = useTranslation(); + + const [state, setState] = React.useState<"input" | "process">("input"); + const [kind, setKind] = React.useState<"text" | "image">("text"); + const [text, setText] = React.useState<string>(""); + const [imageBlob, setImageBlob] = React.useState<Blob | null>(null); + + const draftLocalStorageKey = `timeline.${props.timelineUniqueId}.postDraft`; + + React.useEffect(() => { + setText(window.localStorage.getItem(draftLocalStorageKey) ?? ""); + }, [draftLocalStorageKey]); + + const canSend = kind === "text" || (kind === "image" && imageBlob != null); + + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const containerRef = React.useRef<HTMLDivElement>(null!); + + const notifyHeightChange = (): void => { + if (props.onHeightChange) { + props.onHeightChange(containerRef.current.clientHeight); + } + }; + + React.useEffect(() => { + if (props.onHeightChange) { + props.onHeightChange(containerRef.current.clientHeight); + } + return () => { + if (props.onHeightChange) { + props.onHeightChange(0); + } + }; + }); + + const toggleKind = React.useCallback(() => { + setKind((oldKind) => (oldKind === "text" ? "image" : "text")); + setImageBlob(null); + }, []); + + const onSend = React.useCallback(() => { + setState("process"); + + const req: TimelineCreatePostRequest = (() => { + switch (kind) { + case "text": + return { + content: { + type: "text", + text: text, + }, + } as TimelineCreatePostRequest; + case "image": + if (imageBlob == null) { + throw new UiLogicError( + "Content type is image but image blob is null." + ); + } + return { + content: { + type: "image", + data: imageBlob, + }, + } as TimelineCreatePostRequest; + default: + throw new UiLogicError("Unknown content type."); + } + })(); + + onPost(req).then( + (_) => { + if (kind === "text") { + setText(""); + window.localStorage.removeItem(draftLocalStorageKey); + } + setState("input"); + setKind("text"); + }, + (_) => { + pushAlert({ + type: "danger", + message: t("timeline.sendPostFailed"), + }); + setState("input"); + } + ); + }, [onPost, kind, text, imageBlob, t, draftLocalStorageKey]); + + const onImageSelect = React.useCallback((blob: Blob | null) => { + setImageBlob(blob); + }, []); + + return ( + <div ref={containerRef} className="container-fluid fixed-bottom bg-light"> + <Row> + <Col className="px-1 py-1"> + {kind === "text" ? ( + <textarea + className="w-100 h-100 timeline-post-edit" + value={text} + disabled={state === "process"} + onChange={(event: React.ChangeEvent<HTMLTextAreaElement>) => { + const value = event.currentTarget.value; + setText(value); + window.localStorage.setItem(draftLocalStorageKey, value); + }} + /> + ) : ( + <TimelinePostEditImage onSelect={onImageSelect} /> + )} + </Col> + <Col sm="col-auto align-self-end m-1"> + {(() => { + if (state === "input") { + return ( + <> + <div className="d-block text-center mt-1 mb-2"> + <Svg + onLoad={notifyHeightChange} + src={kind === "text" ? imageIcon : textIcon} + className="icon-button" + onClick={toggleKind} + /> + </div> + <Button color="primary" onClick={onSend} disabled={!canSend}> + {t("timeline.send")} + </Button> + </> + ); + } else { + return <Spinner />; + } + })()} + </Col> + </Row> + </div> + ); +}; + +export default TimelinePostEdit; diff --git a/Timeline/ClientApp/src/app/timeline/TimelinePropertyChangeDialog.tsx b/Timeline/ClientApp/src/app/timeline/TimelinePropertyChangeDialog.tsx index 93989884..a0eea775 100644 --- a/Timeline/ClientApp/src/app/timeline/TimelinePropertyChangeDialog.tsx +++ b/Timeline/ClientApp/src/app/timeline/TimelinePropertyChangeDialog.tsx @@ -1,72 +1,72 @@ -import React from 'react';
-
-import {
- TimelineVisibility,
- kTimelineVisibilities,
- TimelineChangePropertyRequest,
-} from '../data/timeline';
-
-import OperationDialog, {
- OperationSelectInputInfoOption,
-} from '../common/OperationDialog';
-
-export interface TimelinePropertyInfo {
- visibility: TimelineVisibility;
- description: string;
-}
-
-export interface TimelinePropertyChangeDialogProps {
- open: boolean;
- close: () => void;
- oldInfo: TimelinePropertyInfo;
- onProcess: (request: TimelineChangePropertyRequest) => Promise<void>;
-}
-
-const labelMap: { [key in TimelineVisibility]: string } = {
- Private: 'timeline.visibility.private',
- Public: 'timeline.visibility.public',
- Register: 'timeline.visibility.register',
-};
-
-const TimelinePropertyChangeDialog: React.FC<TimelinePropertyChangeDialogProps> = (
- props
-) => {
- return (
- <OperationDialog
- title={'timeline.dialogChangeProperty.title'}
- titleColor="default"
- inputScheme={[
- {
- type: 'select',
- label: 'timeline.dialogChangeProperty.visibility',
- options: kTimelineVisibilities.map<OperationSelectInputInfoOption>(
- (v) => ({
- label: labelMap[v],
- value: v,
- })
- ),
- initValue: props.oldInfo.visibility,
- },
- {
- type: 'text',
- label: 'timeline.dialogChangeProperty.description',
- initValue: props.oldInfo.description,
- },
- ]}
- open={props.open}
- close={props.close}
- onProcess={([newVisibility, newDescription]) => {
- const req: TimelineChangePropertyRequest = {};
- if (newVisibility !== props.oldInfo.visibility) {
- req.visibility = newVisibility as TimelineVisibility;
- }
- if (newDescription !== props.oldInfo.description) {
- req.description = newDescription as string;
- }
- return props.onProcess(req);
- }}
- />
- );
-};
-
-export default TimelinePropertyChangeDialog;
+import React from "react"; + +import { + TimelineVisibility, + kTimelineVisibilities, + TimelineChangePropertyRequest, +} from "../data/timeline"; + +import OperationDialog, { + OperationSelectInputInfoOption, +} from "../common/OperationDialog"; + +export interface TimelinePropertyInfo { + visibility: TimelineVisibility; + description: string; +} + +export interface TimelinePropertyChangeDialogProps { + open: boolean; + close: () => void; + oldInfo: TimelinePropertyInfo; + onProcess: (request: TimelineChangePropertyRequest) => Promise<void>; +} + +const labelMap: { [key in TimelineVisibility]: string } = { + Private: "timeline.visibility.private", + Public: "timeline.visibility.public", + Register: "timeline.visibility.register", +}; + +const TimelinePropertyChangeDialog: React.FC<TimelinePropertyChangeDialogProps> = ( + props +) => { + return ( + <OperationDialog + title={"timeline.dialogChangeProperty.title"} + titleColor="default" + inputScheme={[ + { + type: "select", + label: "timeline.dialogChangeProperty.visibility", + options: kTimelineVisibilities.map<OperationSelectInputInfoOption>( + (v) => ({ + label: labelMap[v], + value: v, + }) + ), + initValue: props.oldInfo.visibility, + }, + { + type: "text", + label: "timeline.dialogChangeProperty.description", + initValue: props.oldInfo.description, + }, + ]} + open={props.open} + close={props.close} + onProcess={([newVisibility, newDescription]) => { + const req: TimelineChangePropertyRequest = {}; + if (newVisibility !== props.oldInfo.visibility) { + req.visibility = newVisibility as TimelineVisibility; + } + if (newDescription !== props.oldInfo.description) { + req.description = newDescription as string; + } + return props.onProcess(req); + }} + /> + ); +}; + +export default TimelinePropertyChangeDialog; diff --git a/Timeline/ClientApp/src/app/timeline/timeline-ui.sass b/Timeline/ClientApp/src/app/timeline/timeline-ui.sass index 667c1da9..79be64d3 100644 --- a/Timeline/ClientApp/src/app/timeline/timeline-ui.sass +++ b/Timeline/ClientApp/src/app/timeline/timeline-ui.sass @@ -1,35 +1,35 @@ -.info-card-container
- .info-card-collapse-button
- z-index: 1
- position: relative
-
- .info-card-content
- width: 100%
- position: absolute
- transform-origin: right top
- transition: transform 0.5s
-
- &[data-collapse='true']
- .info-card-content
- transform: scale(0)
-
-.timeline-page-top-space
- transition: height 0.5s
-
-.timeline-sync-state-badge
- position: fixed
- top: 0
- right: 0
- z-index: 1
- font-size: 0.8em
- padding: 3px 8px
- border-radius: 5px
- background: #e8fbff
-
-.timeline-sync-state-badge-pin
- display: inline-block
- width: 0.4em
- height: 0.4em
- border-radius: 50%
- vertical-align: middle
- margin-right: 0.6em
+.info-card-container + .info-card-collapse-button + z-index: 1 + position: relative + + .info-card-content + width: 100% + position: absolute + transform-origin: right top + transition: transform 0.5s + + &[data-collapse='true'] + .info-card-content + transform: scale(0) + +.timeline-page-top-space + transition: height 0.5s + +.timeline-sync-state-badge + position: fixed + top: 0 + right: 0 + z-index: 1 + font-size: 0.8em + padding: 3px 8px + border-radius: 5px + background: #e8fbff + +.timeline-sync-state-badge-pin + display: inline-block + width: 0.4em + height: 0.4em + border-radius: 50% + vertical-align: middle + margin-right: 0.6em diff --git a/Timeline/ClientApp/src/app/timeline/timeline.sass b/Timeline/ClientApp/src/app/timeline/timeline.sass index b224e973..d431a4c6 100644 --- a/Timeline/ClientApp/src/app/timeline/timeline.sass +++ b/Timeline/ClientApp/src/app/timeline/timeline.sass @@ -1,131 +1,131 @@ -@use 'sass:color'
-
-.timeline
- display: flex
- flex-direction: column
- z-index: 0
- position: relative
-
-@keyframes timeline-enter-animation-mask-animation
- to
- height: 0
-
-.timeline-enter-animation-mask
- position: absolute
- left: 0
- top: 0
- height: calc(100% + 300px)
- width: 100%
- background: linear-gradient(to top, #ffffff00 0, 200px, white 300px, white)
- z-index: 100
- animation: timeline-enter-animation-mask-animation 5s 0.3s forwards // Give it 0.3s to load, which I think is reasonable
-
-$timeline-line-width: 7px
-$timeline-line-node-radius: 18px
-$timeline-line-color: $primary
-$timeline-line-color-current: #36c2e6
-
-@keyframes timeline-line-node-noncurrent
- from
- background: $timeline-line-color
-
- to
- background: color.adjust($timeline-line-color, $lightness: +10%)
- box-shadow: 0 0 20px 3px color.adjust($timeline-line-color, $lightness: +10%, $alpha: -0.1)
-
-
-@keyframes timeline-line-node-current
- from
- background: $timeline-line-color-current
-
- to
- background: color.adjust($timeline-line-color-current, $lightness: +10%)
- box-shadow: 0 0 20px 3px color.adjust($timeline-line-color-current, $lightness: +10%, $alpha: -0.1)
-
-.timeline-line
- &-area
- display: flex
- flex-direction: column
- align-items: center
- flex: 0 0 auto
- width: 60px
-
- &-segment
- width: $timeline-line-width
- background: $timeline-line-color
-
- &.start
- height: 20px
- flex: 0 0 auto
-
- &.end
- flex: 1 1 auto
-
- &.current-end
- height: 20px
- flex: 0 0 auto
- background: linear-gradient($timeline-line-color-current, transparent)
-
- &-node-container
- flex: 0 0 auto
- position: relative
- width: $timeline-line-node-radius
- height: $timeline-line-node-radius
-
- &-node
- width: $timeline-line-node-radius + 2
- height: $timeline-line-node-radius + 2
- position: absolute
- left: -1px
- top: -1px
- border-radius: 50%
- box-sizing: border-box
- z-index: 1
- animation: 1s infinite alternate
- animation-name: timeline-line-node-noncurrent
-
-
-.current
- .timeline-line
- &-segment
-
- &.start
- background: linear-gradient($timeline-line-color, $timeline-line-color-current)
-
- &.end
- background: $timeline-line-color-current
-
- &-node
- animation-name: timeline-line-node-current
-
-.timeline-pt-start
- padding-top: 18px
-
-.timeline-item-delete-button
- position: absolute
- right: 0
- bottom: 0
-
-.timeline-content
- white-space: pre-line
-
-.timeline-content-image
- max-width: 60%
- max-height: 200px
-
-
-.timeline-post-edit-image
- max-width: 100px
- max-height: 100px
-
-.mask
- background: change-color($color: white, $alpha: 0.8)
- z-index: 100
-
-textarea.timeline-post-edit
- @extend .border-primary
- @extend .rounded
-
- &:focus
- outline: none
- box-shadow: 0 0 5px 0 $primary
+@use 'sass:color' + +.timeline + display: flex + flex-direction: column + z-index: 0 + position: relative + +@keyframes timeline-enter-animation-mask-animation + to + height: 0 + +.timeline-enter-animation-mask + position: absolute + left: 0 + top: 0 + height: calc(100% + 300px) + width: 100% + background: linear-gradient(to top, #ffffff00 0, 200px, white 300px, white) + z-index: 100 + animation: timeline-enter-animation-mask-animation 5s 0.3s forwards // Give it 0.3s to load, which I think is reasonable + +$timeline-line-width: 7px +$timeline-line-node-radius: 18px +$timeline-line-color: $primary +$timeline-line-color-current: #36c2e6 + +@keyframes timeline-line-node-noncurrent + from + background: $timeline-line-color + + to + background: color.adjust($timeline-line-color, $lightness: +10%) + box-shadow: 0 0 20px 3px color.adjust($timeline-line-color, $lightness: +10%, $alpha: -0.1) + + +@keyframes timeline-line-node-current + from + background: $timeline-line-color-current + + to + background: color.adjust($timeline-line-color-current, $lightness: +10%) + box-shadow: 0 0 20px 3px color.adjust($timeline-line-color-current, $lightness: +10%, $alpha: -0.1) + +.timeline-line + &-area + display: flex + flex-direction: column + align-items: center + flex: 0 0 auto + width: 60px + + &-segment + width: $timeline-line-width + background: $timeline-line-color + + &.start + height: 20px + flex: 0 0 auto + + &.end + flex: 1 1 auto + + &.current-end + height: 20px + flex: 0 0 auto + background: linear-gradient($timeline-line-color-current, transparent) + + &-node-container + flex: 0 0 auto + position: relative + width: $timeline-line-node-radius + height: $timeline-line-node-radius + + &-node + width: $timeline-line-node-radius + 2 + height: $timeline-line-node-radius + 2 + position: absolute + left: -1px + top: -1px + border-radius: 50% + box-sizing: border-box + z-index: 1 + animation: 1s infinite alternate + animation-name: timeline-line-node-noncurrent + + +.current + .timeline-line + &-segment + + &.start + background: linear-gradient($timeline-line-color, $timeline-line-color-current) + + &.end + background: $timeline-line-color-current + + &-node + animation-name: timeline-line-node-current + +.timeline-pt-start + padding-top: 18px + +.timeline-item-delete-button + position: absolute + right: 0 + bottom: 0 + +.timeline-content + white-space: pre-line + +.timeline-content-image + max-width: 60% + max-height: 200px + + +.timeline-post-edit-image + max-width: 100px + max-height: 100px + +.mask + background: change-color($color: white, $alpha: 0.8) + z-index: 100 + +textarea.timeline-post-edit + @extend .border-primary + @extend .rounded + + &:focus + outline: none + box-shadow: 0 0 5px 0 $primary diff --git a/Timeline/ClientApp/src/app/tsconfig.json b/Timeline/ClientApp/src/app/tsconfig.json index 17ee69cb..14e6327f 100644 --- a/Timeline/ClientApp/src/app/tsconfig.json +++ b/Timeline/ClientApp/src/app/tsconfig.json @@ -1,13 +1,13 @@ -{
- "extends": "../tsconfig.json",
- "compilerOptions": {
- "lib": [
- "dom",
- "dom.iterable",
- "esnext"
- ]
- },
- "include": [
- "."
- ]
-}
+{ + "extends": "../tsconfig.json", + "compilerOptions": { + "lib": [ + "dom", + "dom.iterable", + "esnext" + ] + }, + "include": [ + "." + ] +} diff --git a/Timeline/ClientApp/src/app/typings.d.ts b/Timeline/ClientApp/src/app/typings.d.ts index 521d38e4..34381682 100644 --- a/Timeline/ClientApp/src/app/typings.d.ts +++ b/Timeline/ClientApp/src/app/typings.d.ts @@ -1,24 +1,24 @@ -declare module '*.png' {
- const content: string;
- export default content;
-}
-
-declare module '*.jpeg' {
- const content: string;
- export default content;
-}
-
-declare module '*.jpg' {
- const content: string;
- export default content;
-}
-
-declare module '*.gif' {
- const content: string;
- export default content;
-}
-
-declare module '*.svg' {
- const content: string;
- export default content;
-}
+declare module "*.png" { + const content: string; + export default content; +} + +declare module "*.jpeg" { + const content: string; + export default content; +} + +declare module "*.jpg" { + const content: string; + export default content; +} + +declare module "*.gif" { + const content: string; + export default content; +} + +declare module "*.svg" { + const content: string; + export default content; +} diff --git a/Timeline/ClientApp/src/app/user/ChangeAvatarDialog.tsx b/Timeline/ClientApp/src/app/user/ChangeAvatarDialog.tsx index f7b25252..7d9f9514 100644 --- a/Timeline/ClientApp/src/app/user/ChangeAvatarDialog.tsx +++ b/Timeline/ClientApp/src/app/user/ChangeAvatarDialog.tsx @@ -1,306 +1,306 @@ -import React, { useState, useEffect } from 'react';
-import { useTranslation } from 'react-i18next';
-import {
- Modal,
- ModalHeader,
- Row,
- Button,
- ModalBody,
- ModalFooter,
-} from 'reactstrap';
-import { AxiosError } from 'axios';
-
-import ImageCropper, { Clip, applyClipToImage } from '../common/ImageCropper';
-import { UiLogicError } from '../common';
-
-export interface ChangeAvatarDialogProps {
- open: boolean;
- close: () => void;
- process: (blob: Blob) => Promise<void>;
-}
-
-const ChangeAvatarDialog: React.FC<ChangeAvatarDialogProps> = (props) => {
- const { t } = useTranslation();
-
- const [file, setFile] = React.useState<File | null>(null);
- const [fileUrl, setFileUrl] = React.useState<string | null>(null);
- const [clip, setClip] = React.useState<Clip | null>(null);
- const [
- cropImgElement,
- setCropImgElement,
- ] = React.useState<HTMLImageElement | null>(null);
- const [resultBlob, setResultBlob] = React.useState<Blob | null>(null);
- const [resultUrl, setResultUrl] = React.useState<string | null>(null);
-
- const [state, setState] = React.useState<
- | 'select'
- | 'crop'
- | 'processcrop'
- | 'preview'
- | 'uploading'
- | 'success'
- | 'error'
- >('select');
-
- const [message, setMessage] = useState<
- string | { type: 'custom'; text: string } | null
- >('userPage.dialogChangeAvatar.prompt.select');
-
- const trueMessage =
- message == null
- ? null
- : typeof message === 'string'
- ? t(message)
- : message.text;
-
- const closeDialog = props.close;
-
- const toggle = React.useCallback((): void => {
- if (!(state === 'uploading')) {
- closeDialog();
- }
- }, [state, closeDialog]);
-
- useEffect(() => {
- if (file != null) {
- const url = URL.createObjectURL(file);
- setClip(null);
- setFileUrl(url);
- setState('crop');
- return () => {
- URL.revokeObjectURL(url);
- };
- } else {
- setFileUrl(null);
- setState('select');
- }
- }, [file]);
-
- React.useEffect(() => {
- if (resultBlob != null) {
- const url = URL.createObjectURL(resultBlob);
- setResultUrl(url);
- setState('preview');
- return () => {
- URL.revokeObjectURL(url);
- };
- } else {
- setResultUrl(null);
- }
- }, [resultBlob]);
-
- const onSelectFile = React.useCallback(
- (e: React.ChangeEvent<HTMLInputElement>): void => {
- const files = e.target.files;
- if (files == null || files.length === 0) {
- setFile(null);
- } else {
- setFile(files[0]);
- }
- },
- []
- );
-
- const onCropNext = React.useCallback(() => {
- if (
- cropImgElement == null ||
- clip == null ||
- clip.width === 0 ||
- file == null
- ) {
- throw new UiLogicError();
- }
-
- setState('processcrop');
- void applyClipToImage(cropImgElement, clip, file.type).then((b) => {
- setResultBlob(b);
- });
- }, [cropImgElement, clip, file]);
-
- const onCropPrevious = React.useCallback(() => {
- setFile(null);
- setState('select');
- }, []);
-
- const onPreviewPrevious = React.useCallback(() => {
- setResultBlob(null);
- setState('crop');
- }, []);
-
- const process = props.process;
-
- const upload = React.useCallback(() => {
- if (resultBlob == null) {
- throw new UiLogicError();
- }
-
- setState('uploading');
- process(resultBlob).then(
- () => {
- setState('success');
- },
- (e: unknown) => {
- setState('error');
- setMessage({ type: 'custom', text: (e as AxiosError).message });
- }
- );
- }, [resultBlob, process]);
-
- const createPreviewRow = (): React.ReactElement => {
- if (resultUrl == null) {
- throw new UiLogicError();
- }
- return (
- <Row className="justify-content-center">
- <img
- className="change-avatar-img"
- src={resultUrl}
- alt={t('userPage.dialogChangeAvatar.previewImgAlt')}
- />
- </Row>
- );
- };
-
- return (
- <Modal isOpen={props.open} toggle={toggle}>
- <ModalHeader> {t('userPage.dialogChangeAvatar.title')}</ModalHeader>
- {(() => {
- if (state === 'select') {
- return (
- <>
- <ModalBody className="container">
- <Row>{t('userPage.dialogChangeAvatar.prompt.select')}</Row>
- <Row>
- <input type="file" accept="image/*" onChange={onSelectFile} />
- </Row>
- </ModalBody>
- <ModalFooter>
- <Button color="secondary" onClick={toggle}>
- {t('operationDialog.cancel')}
- </Button>
- </ModalFooter>
- </>
- );
- } else if (state === 'crop') {
- if (fileUrl == null) {
- throw new UiLogicError();
- }
- return (
- <>
- <ModalBody className="container">
- <Row className="justify-content-center">
- <ImageCropper
- clip={clip}
- onChange={setClip}
- imageUrl={fileUrl}
- imageElementCallback={setCropImgElement}
- />
- </Row>
- <Row>{t('userPage.dialogChangeAvatar.prompt.crop')}</Row>
- </ModalBody>
- <ModalFooter>
- <Button color="secondary" onClick={toggle}>
- {t('operationDialog.cancel')}
- </Button>
- <Button color="secondary" onClick={onCropPrevious}>
- {t('operationDialog.previousStep')}
- </Button>
- <Button
- color="primary"
- onClick={onCropNext}
- disabled={
- cropImgElement == null || clip == null || clip.width === 0
- }
- >
- {t('operationDialog.nextStep')}
- </Button>
- </ModalFooter>
- </>
- );
- } else if (state === 'processcrop') {
- return (
- <>
- <ModalBody className="container">
- <Row>
- {t('userPage.dialogChangeAvatar.prompt.processingCrop')}
- </Row>
- </ModalBody>
- <ModalFooter>
- <Button color="secondary" onClick={toggle}>
- {t('operationDialog.cancel')}
- </Button>
- <Button color="secondary" onClick={onPreviewPrevious}>
- {t('operationDialog.previousStep')}
- </Button>
- </ModalFooter>
- </>
- );
- } else if (state === 'preview') {
- return (
- <>
- <ModalBody className="container">
- {createPreviewRow()}
- <Row>{t('userPage.dialogChangeAvatar.prompt.preview')}</Row>
- </ModalBody>
- <ModalFooter>
- <Button color="secondary" onClick={toggle}>
- {t('operationDialog.cancel')}
- </Button>
- <Button color="secondary" onClick={onPreviewPrevious}>
- {t('operationDialog.previousStep')}
- </Button>
- <Button color="primary" onClick={upload}>
- {t('userPage.dialogChangeAvatar.upload')}
- </Button>
- </ModalFooter>
- </>
- );
- } else if (state === 'uploading') {
- return (
- <>
- <ModalBody className="container">
- {createPreviewRow()}
- <Row>{t('userPage.dialogChangeAvatar.prompt.uploading')}</Row>
- </ModalBody>
- <ModalFooter></ModalFooter>
- </>
- );
- } else if (state === 'success') {
- return (
- <>
- <ModalBody className="container">
- <Row className="p-4 text-success">
- {t('operationDialog.success')}
- </Row>
- </ModalBody>
- <ModalFooter>
- <Button color="success" onClick={toggle}>
- {t('operationDialog.ok')}
- </Button>
- </ModalFooter>
- </>
- );
- } else {
- return (
- <>
- <ModalBody className="container">
- {createPreviewRow()}
- <Row className="text-danger">{trueMessage}</Row>
- </ModalBody>
- <ModalFooter>
- <Button color="secondary" onClick={toggle}>
- {t('operationDialog.cancel')}
- </Button>
- <Button color="primary" onClick={upload}>
- {t('operationDialog.retry')}
- </Button>
- </ModalFooter>
- </>
- );
- }
- })()}
- </Modal>
- );
-};
-
-export default ChangeAvatarDialog;
+import React, { useState, useEffect } from "react"; +import { useTranslation } from "react-i18next"; +import { + Modal, + ModalHeader, + Row, + Button, + ModalBody, + ModalFooter, +} from "reactstrap"; +import { AxiosError } from "axios"; + +import ImageCropper, { Clip, applyClipToImage } from "../common/ImageCropper"; +import { UiLogicError } from "../common"; + +export interface ChangeAvatarDialogProps { + open: boolean; + close: () => void; + process: (blob: Blob) => Promise<void>; +} + +const ChangeAvatarDialog: React.FC<ChangeAvatarDialogProps> = (props) => { + const { t } = useTranslation(); + + const [file, setFile] = React.useState<File | null>(null); + const [fileUrl, setFileUrl] = React.useState<string | null>(null); + const [clip, setClip] = React.useState<Clip | null>(null); + const [ + cropImgElement, + setCropImgElement, + ] = React.useState<HTMLImageElement | null>(null); + const [resultBlob, setResultBlob] = React.useState<Blob | null>(null); + const [resultUrl, setResultUrl] = React.useState<string | null>(null); + + const [state, setState] = React.useState< + | "select" + | "crop" + | "processcrop" + | "preview" + | "uploading" + | "success" + | "error" + >("select"); + + const [message, setMessage] = useState< + string | { type: "custom"; text: string } | null + >("userPage.dialogChangeAvatar.prompt.select"); + + const trueMessage = + message == null + ? null + : typeof message === "string" + ? t(message) + : message.text; + + const closeDialog = props.close; + + const toggle = React.useCallback((): void => { + if (!(state === "uploading")) { + closeDialog(); + } + }, [state, closeDialog]); + + useEffect(() => { + if (file != null) { + const url = URL.createObjectURL(file); + setClip(null); + setFileUrl(url); + setState("crop"); + return () => { + URL.revokeObjectURL(url); + }; + } else { + setFileUrl(null); + setState("select"); + } + }, [file]); + + React.useEffect(() => { + if (resultBlob != null) { + const url = URL.createObjectURL(resultBlob); + setResultUrl(url); + setState("preview"); + return () => { + URL.revokeObjectURL(url); + }; + } else { + setResultUrl(null); + } + }, [resultBlob]); + + const onSelectFile = React.useCallback( + (e: React.ChangeEvent<HTMLInputElement>): void => { + const files = e.target.files; + if (files == null || files.length === 0) { + setFile(null); + } else { + setFile(files[0]); + } + }, + [] + ); + + const onCropNext = React.useCallback(() => { + if ( + cropImgElement == null || + clip == null || + clip.width === 0 || + file == null + ) { + throw new UiLogicError(); + } + + setState("processcrop"); + void applyClipToImage(cropImgElement, clip, file.type).then((b) => { + setResultBlob(b); + }); + }, [cropImgElement, clip, file]); + + const onCropPrevious = React.useCallback(() => { + setFile(null); + setState("select"); + }, []); + + const onPreviewPrevious = React.useCallback(() => { + setResultBlob(null); + setState("crop"); + }, []); + + const process = props.process; + + const upload = React.useCallback(() => { + if (resultBlob == null) { + throw new UiLogicError(); + } + + setState("uploading"); + process(resultBlob).then( + () => { + setState("success"); + }, + (e: unknown) => { + setState("error"); + setMessage({ type: "custom", text: (e as AxiosError).message }); + } + ); + }, [resultBlob, process]); + + const createPreviewRow = (): React.ReactElement => { + if (resultUrl == null) { + throw new UiLogicError(); + } + return ( + <Row className="justify-content-center"> + <img + className="change-avatar-img" + src={resultUrl} + alt={t("userPage.dialogChangeAvatar.previewImgAlt")} + /> + </Row> + ); + }; + + return ( + <Modal isOpen={props.open} toggle={toggle}> + <ModalHeader> {t("userPage.dialogChangeAvatar.title")}</ModalHeader> + {(() => { + if (state === "select") { + return ( + <> + <ModalBody className="container"> + <Row>{t("userPage.dialogChangeAvatar.prompt.select")}</Row> + <Row> + <input type="file" accept="image/*" onChange={onSelectFile} /> + </Row> + </ModalBody> + <ModalFooter> + <Button color="secondary" onClick={toggle}> + {t("operationDialog.cancel")} + </Button> + </ModalFooter> + </> + ); + } else if (state === "crop") { + if (fileUrl == null) { + throw new UiLogicError(); + } + return ( + <> + <ModalBody className="container"> + <Row className="justify-content-center"> + <ImageCropper + clip={clip} + onChange={setClip} + imageUrl={fileUrl} + imageElementCallback={setCropImgElement} + /> + </Row> + <Row>{t("userPage.dialogChangeAvatar.prompt.crop")}</Row> + </ModalBody> + <ModalFooter> + <Button color="secondary" onClick={toggle}> + {t("operationDialog.cancel")} + </Button> + <Button color="secondary" onClick={onCropPrevious}> + {t("operationDialog.previousStep")} + </Button> + <Button + color="primary" + onClick={onCropNext} + disabled={ + cropImgElement == null || clip == null || clip.width === 0 + } + > + {t("operationDialog.nextStep")} + </Button> + </ModalFooter> + </> + ); + } else if (state === "processcrop") { + return ( + <> + <ModalBody className="container"> + <Row> + {t("userPage.dialogChangeAvatar.prompt.processingCrop")} + </Row> + </ModalBody> + <ModalFooter> + <Button color="secondary" onClick={toggle}> + {t("operationDialog.cancel")} + </Button> + <Button color="secondary" onClick={onPreviewPrevious}> + {t("operationDialog.previousStep")} + </Button> + </ModalFooter> + </> + ); + } else if (state === "preview") { + return ( + <> + <ModalBody className="container"> + {createPreviewRow()} + <Row>{t("userPage.dialogChangeAvatar.prompt.preview")}</Row> + </ModalBody> + <ModalFooter> + <Button color="secondary" onClick={toggle}> + {t("operationDialog.cancel")} + </Button> + <Button color="secondary" onClick={onPreviewPrevious}> + {t("operationDialog.previousStep")} + </Button> + <Button color="primary" onClick={upload}> + {t("userPage.dialogChangeAvatar.upload")} + </Button> + </ModalFooter> + </> + ); + } else if (state === "uploading") { + return ( + <> + <ModalBody className="container"> + {createPreviewRow()} + <Row>{t("userPage.dialogChangeAvatar.prompt.uploading")}</Row> + </ModalBody> + <ModalFooter></ModalFooter> + </> + ); + } else if (state === "success") { + return ( + <> + <ModalBody className="container"> + <Row className="p-4 text-success"> + {t("operationDialog.success")} + </Row> + </ModalBody> + <ModalFooter> + <Button color="success" onClick={toggle}> + {t("operationDialog.ok")} + </Button> + </ModalFooter> + </> + ); + } else { + return ( + <> + <ModalBody className="container"> + {createPreviewRow()} + <Row className="text-danger">{trueMessage}</Row> + </ModalBody> + <ModalFooter> + <Button color="secondary" onClick={toggle}> + {t("operationDialog.cancel")} + </Button> + <Button color="primary" onClick={upload}> + {t("operationDialog.retry")} + </Button> + </ModalFooter> + </> + ); + } + })()} + </Modal> + ); +}; + +export default ChangeAvatarDialog; diff --git a/Timeline/ClientApp/src/app/user/ChangeNicknameDialog.tsx b/Timeline/ClientApp/src/app/user/ChangeNicknameDialog.tsx index 393d88f6..251b18c5 100644 --- a/Timeline/ClientApp/src/app/user/ChangeNicknameDialog.tsx +++ b/Timeline/ClientApp/src/app/user/ChangeNicknameDialog.tsx @@ -1,28 +1,28 @@ -import React from 'react';
-
-import OperationDialog from '../common/OperationDialog';
-
-export interface ChangeNicknameDialogProps {
- open: boolean;
- close: () => void;
- onProcess: (newNickname: string) => Promise<void>;
-}
-
-const ChangeNicknameDialog: React.FC<ChangeNicknameDialogProps> = props => {
- return (
- <OperationDialog
- open={props.open}
- title="userPage.dialogChangeNickname.title"
- titleColor="default"
- inputScheme={[
- { type: 'text', label: 'userPage.dialogChangeNickname.inputLabel' }
- ]}
- onProcess={([newNickname]) => {
- return props.onProcess(newNickname as string);
- }}
- close={props.close}
- />
- );
-};
-
-export default ChangeNicknameDialog;
+import React from "react"; + +import OperationDialog from "../common/OperationDialog"; + +export interface ChangeNicknameDialogProps { + open: boolean; + close: () => void; + onProcess: (newNickname: string) => Promise<void>; +} + +const ChangeNicknameDialog: React.FC<ChangeNicknameDialogProps> = (props) => { + return ( + <OperationDialog + open={props.open} + title="userPage.dialogChangeNickname.title" + titleColor="default" + inputScheme={[ + { type: "text", label: "userPage.dialogChangeNickname.inputLabel" }, + ]} + onProcess={([newNickname]) => { + return props.onProcess(newNickname as string); + }} + close={props.close} + /> + ); +}; + +export default ChangeNicknameDialog; diff --git a/Timeline/ClientApp/src/app/user/Login.tsx b/Timeline/ClientApp/src/app/user/Login.tsx index 2f2a3188..4f9cd05d 100644 --- a/Timeline/ClientApp/src/app/user/Login.tsx +++ b/Timeline/ClientApp/src/app/user/Login.tsx @@ -1,148 +1,148 @@ -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,
- Input,
- Form,
- FormFeedback,
- Spinner,
- Button,
-} from 'reactstrap';
-
-const Login: React.FC = (_) => {
- const { t } = useTranslation();
- const history = useHistory();
- const [username, setUsername] = useState<string>('');
- const [usernameDirty, setUsernameDirty] = useState<boolean>(false);
- const [password, setPassword] = useState<string>('');
- const [passwordDirty, setPasswordDirty] = useState<boolean>(false);
- const [rememberMe, setRememberMe] = useState<boolean>(true);
- const [process, setProcess] = useState<boolean>(false);
- const [error, setError] = useState<string | null>(null);
-
- const user = useUser();
-
- useEffect(() => {
- if (user != null) {
- const id = setTimeout(() => history.push('/'), 3000);
- return () => {
- clearTimeout(id);
- };
- }
- }, [history, user]);
-
- if (user != null) {
- return (
- <>
- <AppBar />
- <p className="mt-appbar">{t('login.alreadyLogin')}</p>
- </>
- );
- }
-
- function onSubmit(event: React.SyntheticEvent): void {
- if (username === '' || password === '') {
- setUsernameDirty(true);
- setPasswordDirty(true);
- return;
- }
-
- setProcess(true);
- userService
- .login(
- {
- username: username,
- password: password,
- },
- rememberMe
- )
- .then(
- () => {
- if (history.length === 0) {
- history.push('/');
- } else {
- history.goBack();
- }
- },
- (e: Error) => {
- setProcess(false);
- setError(e.message);
- }
- );
- event.preventDefault();
- }
-
- return (
- <Fragment>
- <AppBar />
- <div className="container login-container mt-appbar">
- <h1>{t('welcome')}</h1>
- <Form>
- <FormGroup>
- <Label for="username">{t('user.username')}</Label>
- <Input
- id="username"
- disabled={process}
- onChange={(e) => {
- setUsername(e.target.value);
- setUsernameDirty(true);
- }}
- value={username}
- invalid={usernameDirty && username === ''}
- />
- {usernameDirty && username === '' && (
- <FormFeedback>{t('login.emptyUsername')}</FormFeedback>
- )}
- </FormGroup>
- <FormGroup>
- <Label for="password">{t('user.password')}</Label>
- <Input
- id="password"
- type="password"
- disabled={process}
- onChange={(e) => {
- setPassword(e.target.value);
- setPasswordDirty(true);
- }}
- value={password}
- invalid={passwordDirty && password === ''}
- />
- {passwordDirty && password === '' && (
- <FormFeedback>{t('login.emptyPassword')}</FormFeedback>
- )}
- </FormGroup>
- <FormGroup check>
- <Input
- id="remember-me"
- type="checkbox"
- checked={rememberMe}
- onChange={(e) => {
- const v = (e.target as HTMLInputElement).checked;
- setRememberMe(v);
- }}
- />
- <Label for="remember-me">{t('user.rememberMe')}</Label>
- </FormGroup>
- {error ? <p className="text-error">{t(error)}</p> : null}
- <div>
- {process ? (
- <Spinner />
- ) : (
- <Button color="primary" onClick={onSubmit}>
- {t('user.login')}
- </Button>
- )}
- </div>
- </Form>
- </div>
- </Fragment>
- );
-};
-
-export default Login;
+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, + Input, + Form, + FormFeedback, + Spinner, + Button, +} from "reactstrap"; + +const Login: React.FC = (_) => { + const { t } = useTranslation(); + const history = useHistory(); + const [username, setUsername] = useState<string>(""); + const [usernameDirty, setUsernameDirty] = useState<boolean>(false); + const [password, setPassword] = useState<string>(""); + const [passwordDirty, setPasswordDirty] = useState<boolean>(false); + const [rememberMe, setRememberMe] = useState<boolean>(true); + const [process, setProcess] = useState<boolean>(false); + const [error, setError] = useState<string | null>(null); + + const user = useUser(); + + useEffect(() => { + if (user != null) { + const id = setTimeout(() => history.push("/"), 3000); + return () => { + clearTimeout(id); + }; + } + }, [history, user]); + + if (user != null) { + return ( + <> + <AppBar /> + <p className="mt-appbar">{t("login.alreadyLogin")}</p> + </> + ); + } + + function onSubmit(event: React.SyntheticEvent): void { + if (username === "" || password === "") { + setUsernameDirty(true); + setPasswordDirty(true); + return; + } + + setProcess(true); + userService + .login( + { + username: username, + password: password, + }, + rememberMe + ) + .then( + () => { + if (history.length === 0) { + history.push("/"); + } else { + history.goBack(); + } + }, + (e: Error) => { + setProcess(false); + setError(e.message); + } + ); + event.preventDefault(); + } + + return ( + <Fragment> + <AppBar /> + <div className="container login-container mt-appbar"> + <h1>{t("welcome")}</h1> + <Form> + <FormGroup> + <Label for="username">{t("user.username")}</Label> + <Input + id="username" + disabled={process} + onChange={(e) => { + setUsername(e.target.value); + setUsernameDirty(true); + }} + value={username} + invalid={usernameDirty && username === ""} + /> + {usernameDirty && username === "" && ( + <FormFeedback>{t("login.emptyUsername")}</FormFeedback> + )} + </FormGroup> + <FormGroup> + <Label for="password">{t("user.password")}</Label> + <Input + id="password" + type="password" + disabled={process} + onChange={(e) => { + setPassword(e.target.value); + setPasswordDirty(true); + }} + value={password} + invalid={passwordDirty && password === ""} + /> + {passwordDirty && password === "" && ( + <FormFeedback>{t("login.emptyPassword")}</FormFeedback> + )} + </FormGroup> + <FormGroup check> + <Input + id="remember-me" + type="checkbox" + checked={rememberMe} + onChange={(e) => { + const v = (e.target as HTMLInputElement).checked; + setRememberMe(v); + }} + /> + <Label for="remember-me">{t("user.rememberMe")}</Label> + </FormGroup> + {error ? <p className="text-error">{t(error)}</p> : null} + <div> + {process ? ( + <Spinner /> + ) : ( + <Button color="primary" onClick={onSubmit}> + {t("user.login")} + </Button> + )} + </div> + </Form> + </div> + </Fragment> + ); +}; + +export default Login; diff --git a/Timeline/ClientApp/src/app/user/User.tsx b/Timeline/ClientApp/src/app/user/User.tsx index 67c9d921..6f61cacf 100644 --- a/Timeline/ClientApp/src/app/user/User.tsx +++ b/Timeline/ClientApp/src/app/user/User.tsx @@ -1,77 +1,77 @@ -import React, { useState } from 'react';
-import { useParams } from 'react-router';
-
-import { UiLogicError } from '../common';
-import { useUser, userInfoService } from '../data/user';
-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 = (_) => {
- const { username } = useParams<{ username: string }>();
-
- const user = useUser();
-
- const [dialog, setDialog] = useState<null | PersonalTimelineManageItem>(null);
- const [dataKey, setDataKey] = useState<number>(0);
-
- let dialogElement: React.ReactElement | undefined;
-
- const closeDialogHandler = (): void => {
- setDialog(null);
- };
-
- if (dialog === 'nickname') {
- if (user == null) {
- throw new UiLogicError('Change nickname without login.');
- }
-
- dialogElement = (
- <ChangeNicknameDialog
- open
- close={closeDialogHandler}
- onProcess={(newNickname) => {
- const p = changeNickname(user.token, username, newNickname);
- return p.then((_) => {
- setDataKey(dataKey + 1);
- });
- }}
- />
- );
- } else if (dialog === 'avatar') {
- if (user == null) {
- throw new UiLogicError('Change avatar without login.');
- }
-
- dialogElement = (
- <ChangeAvatarDialog
- open
- close={closeDialogHandler}
- process={(file) => userInfoService.setAvatar(username, file)}
- />
- );
- }
-
- const onManage = React.useCallback((item: PersonalTimelineManageItem) => {
- setDialog(item);
- }, []);
-
- return (
- <>
- <TimelinePageTemplate
- dataVersion={dataKey}
- name={`@${username}`}
- UiComponent={UserPage}
- onManage={onManage}
- notFoundI18nKey="timeline.userNotExist"
- />
- {dialogElement}
- </>
- );
-};
-
-export default User;
+import React, { useState } from "react"; +import { useParams } from "react-router"; + +import { UiLogicError } from "../common"; +import { useUser, userInfoService } from "../data/user"; +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 = (_) => { + const { username } = useParams<{ username: string }>(); + + const user = useUser(); + + const [dialog, setDialog] = useState<null | PersonalTimelineManageItem>(null); + const [dataKey, setDataKey] = useState<number>(0); + + let dialogElement: React.ReactElement | undefined; + + const closeDialogHandler = (): void => { + setDialog(null); + }; + + if (dialog === "nickname") { + if (user == null) { + throw new UiLogicError("Change nickname without login."); + } + + dialogElement = ( + <ChangeNicknameDialog + open + close={closeDialogHandler} + onProcess={(newNickname) => { + const p = changeNickname(user.token, username, newNickname); + return p.then((_) => { + setDataKey(dataKey + 1); + }); + }} + /> + ); + } else if (dialog === "avatar") { + if (user == null) { + throw new UiLogicError("Change avatar without login."); + } + + dialogElement = ( + <ChangeAvatarDialog + open + close={closeDialogHandler} + process={(file) => userInfoService.setAvatar(username, file)} + /> + ); + } + + const onManage = React.useCallback((item: PersonalTimelineManageItem) => { + setDialog(item); + }, []); + + return ( + <> + <TimelinePageTemplate + dataVersion={dataKey} + name={`@${username}`} + UiComponent={UserPage} + onManage={onManage} + notFoundI18nKey="timeline.userNotExist" + /> + {dialogElement} + </> + ); +}; + +export default User; 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; diff --git a/Timeline/ClientApp/src/app/user/UserPage.tsx b/Timeline/ClientApp/src/app/user/UserPage.tsx index 4c9bd747..42f174d9 100644 --- a/Timeline/ClientApp/src/app/user/UserPage.tsx +++ b/Timeline/ClientApp/src/app/user/UserPage.tsx @@ -1,19 +1,19 @@ -import React from 'react';
-
-import { ExcludeKey } from '../utilities/type';
-
-import TimelinePageTemplateUI, {
- TimelinePageTemplateUIProps,
-} from '../timeline/TimelinePageTemplateUI';
-import UserInfoCard, { PersonalTimelineManageItem } from './UserInfoCard';
-
-export type UserPageProps = ExcludeKey<
- TimelinePageTemplateUIProps<PersonalTimelineManageItem>,
- 'CardComponent'
->;
-
-const UserPage: React.FC<UserPageProps> = (props) => {
- return <TimelinePageTemplateUI {...props} CardComponent={UserInfoCard} />;
-};
-
-export default UserPage;
+import React from "react"; + +import { ExcludeKey } from "../utilities/type"; + +import TimelinePageTemplateUI, { + TimelinePageTemplateUIProps, +} from "../timeline/TimelinePageTemplateUI"; +import UserInfoCard, { PersonalTimelineManageItem } from "./UserInfoCard"; + +export type UserPageProps = ExcludeKey< + TimelinePageTemplateUIProps<PersonalTimelineManageItem>, + "CardComponent" +>; + +const UserPage: React.FC<UserPageProps> = (props) => { + return <TimelinePageTemplateUI {...props} CardComponent={UserInfoCard} />; +}; + +export default UserPage; diff --git a/Timeline/ClientApp/src/app/user/api.ts b/Timeline/ClientApp/src/app/user/api.ts index b2026861..e69acbdb 100644 --- a/Timeline/ClientApp/src/app/user/api.ts +++ b/Timeline/ClientApp/src/app/user/api.ts @@ -1,10 +1,10 @@ -import { getHttpUserClient } from '../http/user';
-import { User } from '../data/user';
-
-export function changeNickname(
- token: string,
- username: string,
- newNickname: string
-): Promise<User> {
- return getHttpUserClient().patch(username, { nickname: newNickname }, token);
-}
+import { getHttpUserClient } from "../http/user"; +import { User } from "../data/user"; + +export function changeNickname( + token: string, + username: string, + newNickname: string +): Promise<User> { + return getHttpUserClient().patch(username, { nickname: newNickname }, token); +} diff --git a/Timeline/ClientApp/src/app/user/user-page.sass b/Timeline/ClientApp/src/app/user/user-page.sass index 1e2e802b..ca2d10f5 100644 --- a/Timeline/ClientApp/src/app/user/user-page.sass +++ b/Timeline/ClientApp/src/app/user/user-page.sass @@ -1,11 +1,10 @@ -.login-container
- max-width: 600px
-
-.change-avatar-cropper-row
- max-height: 400px
-
-.change-avatar-img
- min-width: 50%
- max-width: 100%
- max-height: 400px
-
+.login-container + max-width: 600px + +.change-avatar-cropper-row + max-height: 400px + +.change-avatar-img + min-width: 50% + max-width: 100% + max-height: 400px diff --git a/Timeline/ClientApp/src/app/utilities/rxjs.ts b/Timeline/ClientApp/src/app/utilities/rxjs.ts index 1be49164..0730b899 100644 --- a/Timeline/ClientApp/src/app/utilities/rxjs.ts +++ b/Timeline/ClientApp/src/app/utilities/rxjs.ts @@ -1,14 +1,14 @@ -import { OperatorFunction } from 'rxjs';
-import { catchError } from 'rxjs/operators';
-
-export function convertError<T, NewError>(
- oldErrorType: { new (...args: never[]): unknown },
- newErrorType: { new (): NewError }
-): OperatorFunction<T, T> {
- return catchError((error) => {
- if (error instanceof oldErrorType) {
- throw new newErrorType();
- }
- throw error;
- });
-}
+import { OperatorFunction } from "rxjs"; +import { catchError } from "rxjs/operators"; + +export function convertError<T, NewError>( + oldErrorType: { new (...args: never[]): unknown }, + newErrorType: { new (): NewError } +): OperatorFunction<T, T> { + return catchError((error) => { + if (error instanceof oldErrorType) { + throw new newErrorType(); + } + throw error; + }); +} diff --git a/Timeline/ClientApp/src/app/utilities/type.ts b/Timeline/ClientApp/src/app/utilities/type.ts index 307e5825..8df9bf0f 100644 --- a/Timeline/ClientApp/src/app/utilities/type.ts +++ b/Timeline/ClientApp/src/app/utilities/type.ts @@ -1 +1 @@ -export type ExcludeKey<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
+export type ExcludeKey<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>; diff --git a/Timeline/ClientApp/src/app/utilities/url.ts b/Timeline/ClientApp/src/app/utilities/url.ts index 90923fd2..17ead5b2 100644 --- a/Timeline/ClientApp/src/app/utilities/url.ts +++ b/Timeline/ClientApp/src/app/utilities/url.ts @@ -1,52 +1,52 @@ -//copied from https://stackoverflow.com/questions/5999118/how-can-i-add-or-update-a-query-string-parameter
-export function updateQueryString(
- key: string,
- value: undefined | string | null,
- url: string
-): string {
- const re = new RegExp('([?&])' + key + '=.*?(&|#|$)(.*)', 'gi');
- let hash;
-
- if (re.test(url)) {
- if (typeof value !== 'undefined' && value !== null) {
- return url.replace(re, '$1' + key + '=' + value + '$2$3');
- } else {
- hash = url.split('#');
- url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, '');
- if (typeof hash[1] !== 'undefined' && hash[1] !== null) {
- url += '#' + hash[1];
- }
- return url;
- }
- } else {
- if (typeof value !== 'undefined' && value !== null) {
- const separator = url.includes('?') ? '&' : '?';
- hash = url.split('#');
- url = hash[0] + separator + key + '=' + value;
- if (typeof hash[1] !== 'undefined' && hash[1] !== null) {
- url += '#' + hash[1];
- }
- return url;
- } else {
- return url;
- }
- }
-}
-
-export function applyQueryParameters<T>(url: string, query: T): string {
- if (query == null) return url;
-
- for (const [key, value] of Object.entries(query)) {
- if (typeof value === 'string') url = updateQueryString(key, value, url);
- else if (typeof value === 'number')
- url = updateQueryString(key, String(value), url);
- else if (typeof value === 'boolean')
- url = updateQueryString(key, value ? 'true' : 'false', url);
- else if (value instanceof Date)
- url = updateQueryString(key, value.toISOString(), url);
- else {
- console.error('Unknown query parameter type. Param: ', value);
- }
- }
- return url;
-}
+//copied from https://stackoverflow.com/questions/5999118/how-can-i-add-or-update-a-query-string-parameter +export function updateQueryString( + key: string, + value: undefined | string | null, + url: string +): string { + const re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"); + let hash; + + if (re.test(url)) { + if (typeof value !== "undefined" && value !== null) { + return url.replace(re, "$1" + key + "=" + value + "$2$3"); + } else { + hash = url.split("#"); + url = hash[0].replace(re, "$1$3").replace(/(&|\?)$/, ""); + if (typeof hash[1] !== "undefined" && hash[1] !== null) { + url += "#" + hash[1]; + } + return url; + } + } else { + if (typeof value !== "undefined" && value !== null) { + const separator = url.includes("?") ? "&" : "?"; + hash = url.split("#"); + url = hash[0] + separator + key + "=" + value; + if (typeof hash[1] !== "undefined" && hash[1] !== null) { + url += "#" + hash[1]; + } + return url; + } else { + return url; + } + } +} + +export function applyQueryParameters<T>(url: string, query: T): string { + if (query == null) return url; + + for (const [key, value] of Object.entries(query)) { + if (typeof value === "string") url = updateQueryString(key, value, url); + else if (typeof value === "number") + url = updateQueryString(key, String(value), url); + else if (typeof value === "boolean") + url = updateQueryString(key, value ? "true" : "false", url); + else if (value instanceof Date) + url = updateQueryString(key, value.toISOString(), url); + else { + console.error("Unknown query parameter type. Param: ", value); + } + } + return url; +} diff --git a/Timeline/ClientApp/src/sw/sw.ts b/Timeline/ClientApp/src/sw/sw.ts index 9d62757a..d6202f36 100644 --- a/Timeline/ClientApp/src/sw/sw.ts +++ b/Timeline/ClientApp/src/sw/sw.ts @@ -1,28 +1,28 @@ -import { precacheAndRoute, matchPrecache } from 'workbox-precaching';
-import { setDefaultHandler } from 'workbox-routing';
-import { NetworkOnly } from 'workbox-strategies';
-
-declare let self: ServiceWorkerGlobalScope;
-
-self.addEventListener('message', (event) => {
- if (event.data && (event.data as { type: string }).type === 'SKIP_WAITING') {
- void self.skipWaiting();
- }
-});
-
-precacheAndRoute(self.__WB_MANIFEST);
-
-const networkOnly = new NetworkOnly();
-
-setDefaultHandler((options) => {
- const { request, url } = options;
- if (url && url.pathname.startsWith('/api/')) {
- return networkOnly.handle(options);
- }
-
- if (request instanceof Request && request.destination === 'document')
- return matchPrecache('/index.html').then((r) =>
- r == null ? Response.error() : r
- );
- else return networkOnly.handle(options);
-});
+import { precacheAndRoute, matchPrecache } from "workbox-precaching"; +import { setDefaultHandler } from "workbox-routing"; +import { NetworkOnly } from "workbox-strategies"; + +declare let self: ServiceWorkerGlobalScope; + +self.addEventListener("message", (event) => { + if (event.data && (event.data as { type: string }).type === "SKIP_WAITING") { + void self.skipWaiting(); + } +}); + +precacheAndRoute(self.__WB_MANIFEST); + +const networkOnly = new NetworkOnly(); + +setDefaultHandler((options) => { + const { request, url } = options; + if (url && url.pathname.startsWith("/api/")) { + return networkOnly.handle(options); + } + + if (request instanceof Request && request.destination === "document") + return matchPrecache("/index.html").then((r) => + r == null ? Response.error() : r + ); + else return networkOnly.handle(options); +}); diff --git a/Timeline/ClientApp/src/sw/tsconfig.json b/Timeline/ClientApp/src/sw/tsconfig.json index 71fc0bcd..aac99e59 100644 --- a/Timeline/ClientApp/src/sw/tsconfig.json +++ b/Timeline/ClientApp/src/sw/tsconfig.json @@ -1,12 +1,12 @@ -{
- "extends": "../tsconfig.json",
- "compilerOptions": {
- "lib": [
- "esnext",
- "webworker"
- ]
- },
- "include": [
- "."
- ]
-}
+{ + "extends": "../tsconfig.json", + "compilerOptions": { + "lib": [ + "esnext", + "webworker" + ] + }, + "include": [ + "." + ] +} diff --git a/Timeline/ClientApp/src/tsconfig.json b/Timeline/ClientApp/src/tsconfig.json index 00277635..2820b583 100644 --- a/Timeline/ClientApp/src/tsconfig.json +++ b/Timeline/ClientApp/src/tsconfig.json @@ -1,17 +1,17 @@ -{
- "compilerOptions": {
- "target": "esnext",
- "allowJs": true,
- "skipLibCheck": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "strict": true,
- "forceConsistentCasingInFileNames": true,
- "module": "esnext",
- "moduleResolution": "node",
- "resolveJsonModule": true,
- "isolatedModules": true,
- "jsx": "preserve",
- "sourceMap": true
- }
-}
\ No newline at end of file +{ + "compilerOptions": { + "target": "esnext", + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "sourceMap": true + } +} diff --git a/Timeline/ClientApp/webpack.common.js b/Timeline/ClientApp/webpack.common.js index b8e2a5f6..fdfb793e 100644 --- a/Timeline/ClientApp/webpack.common.js +++ b/Timeline/ClientApp/webpack.common.js @@ -1,94 +1,94 @@ -const path = require('path');
-const HtmlWebpackPlugin = require('html-webpack-plugin');
-const PnpWebpackPlugin = require('pnp-webpack-plugin');
-const postcssPresetEnv = require('postcss-preset-env');
-const Config = require('webpack-chain');
+const path = require("path");
+const HtmlWebpackPlugin = require("html-webpack-plugin");
+const PnpWebpackPlugin = require("pnp-webpack-plugin");
+const postcssPresetEnv = require("postcss-preset-env");
+const Config = require("webpack-chain");
const config = new Config();
-config.entry('index').add(path.resolve(__dirname, 'src/app/index.tsx'));
+config.entry("index").add(path.resolve(__dirname, "src/app/index.tsx"));
config.module
- .rule('ts')
+ .rule("ts")
.test(/\.ts(x?)$/)
.exclude.add(/node_modules/)
.end()
- .use('babel')
- .loader('babel-loader')
+ .use("babel")
+ .loader("babel-loader")
.end()
- .use('ts')
- .loader('ts-loader')
+ .use("ts")
+ .loader("ts-loader")
.end();
config.module
- .rule('js')
+ .rule("js")
.test(/\.js(x?)$/)
.exclude.add(/node_modules/)
.end()
- .use('babel')
- .loader('babel-loader')
+ .use("babel")
+ .loader("babel-loader")
.end();
config.module
- .rule('css')
+ .rule("css")
.test(/\.css$/)
- .use('css')
- .loader('css-loader')
+ .use("css")
+ .loader("css-loader")
.end()
- .use('postcss')
- .loader('postcss-loader')
+ .use("postcss")
+ .loader("postcss-loader")
.options({
plugins: () => [postcssPresetEnv(/* pluginOptions */)],
})
.end();
config.module
- .rule('sass')
+ .rule("sass")
.test(/\.(scss|sass)$/)
- .use('css')
- .loader('css-loader')
+ .use("css")
+ .loader("css-loader")
.end()
- .use('postcss')
- .loader('postcss-loader')
+ .use("postcss")
+ .loader("postcss-loader")
.options({
plugins: () => [postcssPresetEnv(/* pluginOptions */)],
})
.end()
- .use('sass')
- .loader('sass-loader')
+ .use("sass")
+ .loader("sass-loader")
.end();
config.module
- .rule('file')
+ .rule("file")
.test(/\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot)$/i)
- .use('url')
- .loader('url-loader')
+ .use("url")
+ .loader("url-loader")
.options({
limit: 8192,
});
config.resolve.extensions
- .add('*')
- .add('.js')
- .add('.jsx')
- .add('.ts')
- .add('.tsx')
+ .add("*")
+ .add(".js")
+ .add(".jsx")
+ .add(".ts")
+ .add(".tsx")
.end()
- .plugin('pnp')
+ .plugin("pnp")
.use(PnpWebpackPlugin);
-config.resolveLoader.plugin('pnp').use(PnpWebpackPlugin.moduleLoader(module));
+config.resolveLoader.plugin("pnp").use(PnpWebpackPlugin.moduleLoader(module));
config.output
- .path(path.resolve(__dirname, 'dist/'))
- .filename('[name].[hash].js')
- .chunkFilename('[name].[hash].js')
- .publicPath('/');
+ .path(path.resolve(__dirname, "dist/"))
+ .filename("[name].[hash].js")
+ .chunkFilename("[name].[hash].js")
+ .publicPath("/");
-config.plugin('html').use(HtmlWebpackPlugin, [
+config.plugin("html").use(HtmlWebpackPlugin, [
{
- template: 'src/app/index.ejs',
- title: 'Timeline',
+ template: "src/app/index.ejs",
+ title: "Timeline",
},
]);
diff --git a/Timeline/ClientApp/webpack.config.dev.js b/Timeline/ClientApp/webpack.config.dev.js index 2fb9e866..fea5a2c5 100644 --- a/Timeline/ClientApp/webpack.config.dev.js +++ b/Timeline/ClientApp/webpack.config.dev.js @@ -1,59 +1,59 @@ -const path = require('path');
-const webpack = require('webpack');
+const path = require("path");
+const webpack = require("webpack");
-const config = require('./webpack.common');
+const config = require("./webpack.common");
-config.mode('development');
+config.mode("development");
-config.entry('index').add('react-hot-loader/patch');
+config.entry("index").add("react-hot-loader/patch");
config.module
- .rule('ts')
- .use('babel')
+ .rule("ts")
+ .use("babel")
.options({
- plugins: ['react-hot-loader/babel'],
+ plugins: ["react-hot-loader/babel"],
});
config.module
- .rule('js')
- .use('babel')
+ .rule("js")
+ .use("babel")
.options({
- plugins: ['react-hot-loader/babel'],
+ plugins: ["react-hot-loader/babel"],
});
config.module
- .rule('css')
- .use('style')
- .before('css')
- .loader('style-loader')
+ .rule("css")
+ .use("style")
+ .before("css")
+ .loader("style-loader")
.end();
config.module
- .rule('sass')
- .use('style')
- .before('css')
- .loader('style-loader')
+ .rule("sass")
+ .use("style")
+ .before("css")
+ .loader("style-loader")
.end();
-config.devtool('eval-cheap-module-source-map');
+config.devtool("eval-cheap-module-source-map");
-config.resolve.alias.set('react-dom', '@hot-loader/react-dom');
+config.resolve.alias.set("react-dom", "@hot-loader/react-dom");
config.devServer
- .contentBase(path.resolve(__dirname, 'public/'))
- .host('0.0.0.0')
+ .contentBase(path.resolve(__dirname, "public/"))
+ .host("0.0.0.0")
.port(3000)
.historyApiFallback(true)
.hotOnly(true)
- .allowedHosts.add('.myide.io');
+ .allowedHosts.add(".myide.io");
-config.plugin('hot').use(webpack.HotModuleReplacementPlugin);
+config.plugin("hot").use(webpack.HotModuleReplacementPlugin);
module.exports = (env) => {
if (env && env.TIMELINE_USE_MOCK_BACKEND) {
config
- .entry('index')
- .add(path.join(__dirname, 'src/app/http/mock/install.ts'));
+ .entry("index")
+ .add(path.join(__dirname, "src/app/http/mock/install.ts"));
}
return config.toConfig();
diff --git a/Timeline/ClientApp/webpack.config.prod.js b/Timeline/ClientApp/webpack.config.prod.js index 5a83a3b8..188cb940 100644 --- a/Timeline/ClientApp/webpack.config.prod.js +++ b/Timeline/ClientApp/webpack.config.prod.js @@ -1,51 +1,51 @@ -const path = require('path');
-const { CleanWebpackPlugin } = require('clean-webpack-plugin');
-const CopyPlugin = require('copy-webpack-plugin');
-const WorkboxPlugin = require('workbox-webpack-plugin');
-const MiniCssExtractPlugin = require('mini-css-extract-plugin');
+const path = require("path");
+const { CleanWebpackPlugin } = require("clean-webpack-plugin");
+const CopyPlugin = require("copy-webpack-plugin");
+const WorkboxPlugin = require("workbox-webpack-plugin");
+const MiniCssExtractPlugin = require("mini-css-extract-plugin");
-const config = require('./webpack.common');
+const config = require("./webpack.common");
-config.mode('production');
+config.mode("production");
config
- .entry('index')
- .add(path.resolve(__dirname, 'src/app/service-worker.tsx'));
+ .entry("index")
+ .add(path.resolve(__dirname, "src/app/service-worker.tsx"));
config.module
- .rule('css')
- .use('mini-css-extract')
- .before('css')
+ .rule("css")
+ .use("mini-css-extract")
+ .before("css")
.loader(MiniCssExtractPlugin.loader)
.end();
config.module
- .rule('sass')
- .use('mini-css-extract')
- .before('css')
+ .rule("sass")
+ .use("mini-css-extract")
+ .before("css")
.loader(MiniCssExtractPlugin.loader)
.end();
-config.devtool('source-map');
+config.devtool("source-map");
-config.plugin('mini-css-extract').use(MiniCssExtractPlugin);
+config.plugin("mini-css-extract").use(MiniCssExtractPlugin);
-config.plugin('clean').use(CleanWebpackPlugin);
+config.plugin("clean").use(CleanWebpackPlugin);
-config.plugin('copy').use(CopyPlugin, [
+config.plugin("copy").use(CopyPlugin, [
{
patterns: [
{
- from: path.resolve(__dirname, 'public/'),
- to: path.resolve(__dirname, 'dist/'),
+ from: path.resolve(__dirname, "public/"),
+ to: path.resolve(__dirname, "dist/"),
},
],
},
]);
-config.plugin('workbox').use(WorkboxPlugin.InjectManifest, [
+config.plugin("workbox").use(WorkboxPlugin.InjectManifest, [
{
- swSrc: path.resolve(__dirname, 'src/sw/sw.ts'),
+ swSrc: path.resolve(__dirname, "src/sw/sw.ts"),
maximumFileSizeToCacheInBytes: 15000000,
},
]);
diff --git a/Timeline/ClientApp/yarn.lock b/Timeline/ClientApp/yarn.lock index cabbef2c..c5ddde3b 100644 --- a/Timeline/ClientApp/yarn.lock +++ b/Timeline/ClientApp/yarn.lock @@ -34,7 +34,42 @@ __metadata: languageName: node
linkType: hard
-"@babel/core@npm:^7.10.5, @babel/core@npm:^7.8.4":
+"@babel/compat-data@npm:^7.11.0":
+ version: 7.11.0
+ resolution: "@babel/compat-data@npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcompat-data%2Fdownload%2F%40babel%2Fcompat-data-7.11.0.tgz"
+ dependencies:
+ browserslist: ^4.12.0
+ invariant: ^2.2.4
+ semver: ^5.5.0
+ checksum: 6c3b3946543f4276e1bafbee03de6699c4cdbf92e236fd593f7793b8a2f78e6addb9ded715d84bc676ab39fda3efee634c23a7cf5b982c3d83381c51cd912b85
+ languageName: node
+ linkType: hard
+
+"@babel/core@npm:^7.11.4":
+ version: 7.11.4
+ resolution: "@babel/core@npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.11.4.tgz"
+ dependencies:
+ "@babel/code-frame": ^7.10.4
+ "@babel/generator": ^7.11.4
+ "@babel/helper-module-transforms": ^7.11.0
+ "@babel/helpers": ^7.10.4
+ "@babel/parser": ^7.11.4
+ "@babel/template": ^7.10.4
+ "@babel/traverse": ^7.11.0
+ "@babel/types": ^7.11.0
+ convert-source-map: ^1.7.0
+ debug: ^4.1.0
+ gensync: ^1.0.0-beta.1
+ json5: ^2.1.2
+ lodash: ^4.17.19
+ resolve: ^1.3.2
+ semver: ^5.4.1
+ source-map: ^0.5.0
+ checksum: 21b40a4242f308c2ccbcc07393bc47ef1ed3f6b4f6db5081801cf4c504926e28e24130bf4afd81ff9b0d6c61cdbb873492c892d0cebdb2e5f5cfb9711b17f089
+ languageName: node
+ linkType: hard
+
+"@babel/core@npm:^7.8.4":
version: 7.10.5
resolution: "@babel/core@npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.10.5.tgz"
dependencies:
@@ -69,6 +104,17 @@ __metadata: languageName: node
linkType: hard
+"@babel/generator@npm:^7.11.0, @babel/generator@npm:^7.11.4":
+ version: 7.11.4
+ resolution: "@babel/generator@npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fgenerator%2Fdownload%2F%40babel%2Fgenerator-7.11.4.tgz"
+ dependencies:
+ "@babel/types": ^7.11.0
+ jsesc: ^2.5.1
+ source-map: ^0.5.0
+ checksum: 1244facf6e03ea120ee6f7520eb7e7347ef97a3ece7ccf5d3efd5a70e6c4f85c67d7e8b9dc533ee071c95d91fe0ff8c1b9cf1a59447f4bc1caddcace64e77dfb
+ languageName: node
+ linkType: hard
+
"@babel/helper-annotate-as-pure@npm:^7.10.4":
version: 7.10.4
resolution: "@babel/helper-annotate-as-pure@npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-annotate-as-pure%2Fdownload%2F%40babel%2Fhelper-annotate-as-pure-7.10.4.tgz"
@@ -236,6 +282,21 @@ __metadata: languageName: node
linkType: hard
+"@babel/helper-module-transforms@npm:^7.11.0":
+ version: 7.11.0
+ resolution: "@babel/helper-module-transforms@npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-transforms%2Fdownload%2F%40babel%2Fhelper-module-transforms-7.11.0.tgz"
+ dependencies:
+ "@babel/helper-module-imports": ^7.10.4
+ "@babel/helper-replace-supers": ^7.10.4
+ "@babel/helper-simple-access": ^7.10.4
+ "@babel/helper-split-export-declaration": ^7.11.0
+ "@babel/template": ^7.10.4
+ "@babel/types": ^7.11.0
+ lodash: ^4.17.19
+ checksum: 8b74d0a729f00c5880ed7927e333a6b4bc31739108fbbbdd94b0cf28599f49c78f1e48f16b12bec0b1c966ba1ca72faf10eb98019617ef470a6885cc891e97f6
+ languageName: node
+ linkType: hard
+
"@babel/helper-optimise-call-expression@npm:^7.10.4":
version: 7.10.4
resolution: "@babel/helper-optimise-call-expression@npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-optimise-call-expression%2Fdownload%2F%40babel%2Fhelper-optimise-call-expression-7.10.4.tgz"
@@ -245,7 +306,7 @@ __metadata: languageName: node
linkType: hard
-"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.8.0":
+"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3":
version: 7.10.4
resolution: "@babel/helper-plugin-utils@npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.10.4.tgz"
checksum: 9f617e619a3557cb5fae8885e91cd94ba4ee16fb345e0360de0d7dc037efb10cc604939ecc1038ccdb71aa37e7e78f20133d7bbbebecb8f6dcdb557650366d92
@@ -296,6 +357,15 @@ __metadata: languageName: node
linkType: hard
+"@babel/helper-skip-transparent-expression-wrappers@npm:^7.11.0":
+ version: 7.11.0
+ resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-skip-transparent-expression-wrappers%2Fdownload%2F%40babel%2Fhelper-skip-transparent-expression-wrappers-7.11.0.tgz"
+ dependencies:
+ "@babel/types": ^7.11.0
+ checksum: c5995c834fbaeb8d573184c54e637add2c1b558f6f8a52a84d0c1777a564b634b94917f2b232d1ee4a96ae34587fdeb28b5dae1a45f3e3620cbff0da340aa287
+ languageName: node
+ linkType: hard
+
"@babel/helper-split-export-declaration@npm:^7.10.4":
version: 7.10.4
resolution: "@babel/helper-split-export-declaration@npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-split-export-declaration%2Fdownload%2F%40babel%2Fhelper-split-export-declaration-7.10.4.tgz"
@@ -305,6 +375,15 @@ __metadata: languageName: node
linkType: hard
+"@babel/helper-split-export-declaration@npm:^7.11.0":
+ version: 7.11.0
+ resolution: "@babel/helper-split-export-declaration@npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-split-export-declaration%2Fdownload%2F%40babel%2Fhelper-split-export-declaration-7.11.0.tgz"
+ dependencies:
+ "@babel/types": ^7.11.0
+ checksum: ddfc44d0cf75ee3a73e71b18e8b9b67d256f6e8496e550ab0b1342ef8cd62dd232c13ac77569e319869b1515a9733863e69a143e76f52e9fc1b51ee374b8869b
+ languageName: node
+ linkType: hard
+
"@babel/helper-validator-identifier@npm:^7.10.4":
version: 7.10.4
resolution: "@babel/helper-validator-identifier@npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-validator-identifier%2Fdownload%2F%40babel%2Fhelper-validator-identifier-7.10.4.tgz"
@@ -355,6 +434,15 @@ __metadata: languageName: node
linkType: hard
+"@babel/parser@npm:^7.11.0, @babel/parser@npm:^7.11.4":
+ version: 7.11.4
+ resolution: "@babel/parser@npm:7.11.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fparser%2Fdownload%2F%40babel%2Fparser-7.11.4.tgz"
+ bin:
+ parser: ./bin/babel-parser.js
+ checksum: 06337dd30f432634503542a489bc4106a7505e7551c2feae0f1d25f35dfed9d1192373b3366ffd3a9a3ee65aeec60bb9c7d0612f9e0cfc17835eae467701b42a
+ languageName: node
+ linkType: hard
+
"@babel/plugin-proposal-async-generator-functions@npm:^7.10.4":
version: 7.10.5
resolution: "@babel/plugin-proposal-async-generator-functions@npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-async-generator-functions%2Fdownload%2F%40babel%2Fplugin-proposal-async-generator-functions-7.10.5.tgz"
@@ -368,7 +456,7 @@ __metadata: languageName: node
linkType: hard
-"@babel/plugin-proposal-class-properties@npm:^7.10.1, @babel/plugin-proposal-class-properties@npm:^7.10.4":
+"@babel/plugin-proposal-class-properties@npm:^7.10.4":
version: 7.10.4
resolution: "@babel/plugin-proposal-class-properties@npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-class-properties%2Fdownload%2F%40babel%2Fplugin-proposal-class-properties-7.10.4.tgz"
dependencies:
@@ -405,6 +493,18 @@ __metadata: languageName: node
linkType: hard
+"@babel/plugin-proposal-export-namespace-from@npm:^7.10.4":
+ version: 7.10.4
+ resolution: "@babel/plugin-proposal-export-namespace-from@npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-export-namespace-from%2Fdownload%2F%40babel%2Fplugin-proposal-export-namespace-from-7.10.4.tgz"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.10.4
+ "@babel/plugin-syntax-export-namespace-from": ^7.8.3
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: b17727e66f86119de1f8b3d7b48351ec2b339f95a7c45238c0c11c9d81491696689d68204d79f45cdede007ed674424a6d255463285c2d66abbb76f09417ae28
+ languageName: node
+ linkType: hard
+
"@babel/plugin-proposal-json-strings@npm:^7.10.4":
version: 7.10.4
resolution: "@babel/plugin-proposal-json-strings@npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-json-strings%2Fdownload%2F%40babel%2Fplugin-proposal-json-strings-7.10.4.tgz"
@@ -417,7 +517,19 @@ __metadata: languageName: node
linkType: hard
-"@babel/plugin-proposal-nullish-coalescing-operator@npm:^7.10.1, @babel/plugin-proposal-nullish-coalescing-operator@npm:^7.10.4":
+"@babel/plugin-proposal-logical-assignment-operators@npm:^7.11.0":
+ version: 7.11.0
+ resolution: "@babel/plugin-proposal-logical-assignment-operators@npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-logical-assignment-operators%2Fdownload%2F%40babel%2Fplugin-proposal-logical-assignment-operators-7.11.0.tgz"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.10.4
+ "@babel/plugin-syntax-logical-assignment-operators": ^7.10.4
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: a87e80bcfdfcbdbd6fa3b34198948d4a9c0e2a8965efcd525215fc8244e7b47f7cb5e69c6c5d42646cdab6aeaebf3e138a33ebe0c44a4163e4ad995b85f008b5
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-proposal-nullish-coalescing-operator@npm:^7.10.4":
version: 7.10.4
resolution: "@babel/plugin-proposal-nullish-coalescing-operator@npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator%2Fdownload%2F%40babel%2Fplugin-proposal-nullish-coalescing-operator-7.10.4.tgz"
dependencies:
@@ -454,6 +566,19 @@ __metadata: languageName: node
linkType: hard
+"@babel/plugin-proposal-object-rest-spread@npm:^7.11.0":
+ version: 7.11.0
+ resolution: "@babel/plugin-proposal-object-rest-spread@npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-proposal-object-rest-spread-7.11.0.tgz"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.10.4
+ "@babel/plugin-syntax-object-rest-spread": ^7.8.0
+ "@babel/plugin-transform-parameters": ^7.10.4
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 5071094245f02ce9b1b090597f51cf8510c7936425ac2358b561447b09bcdd231b5b52896f63cc1a96aa6c2ab7a952b61d9fee6b286686f7dc8697728dd5d66d
+ languageName: node
+ linkType: hard
+
"@babel/plugin-proposal-optional-catch-binding@npm:^7.10.4":
version: 7.10.4
resolution: "@babel/plugin-proposal-optional-catch-binding@npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-proposal-optional-catch-binding-7.10.4.tgz"
@@ -466,7 +591,7 @@ __metadata: languageName: node
linkType: hard
-"@babel/plugin-proposal-optional-chaining@npm:^7.10.1, @babel/plugin-proposal-optional-chaining@npm:^7.10.4":
+"@babel/plugin-proposal-optional-chaining@npm:^7.10.4":
version: 7.10.4
resolution: "@babel/plugin-proposal-optional-chaining@npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-chaining%2Fdownload%2F%40babel%2Fplugin-proposal-optional-chaining-7.10.4.tgz"
dependencies:
@@ -478,6 +603,19 @@ __metadata: languageName: node
linkType: hard
+"@babel/plugin-proposal-optional-chaining@npm:^7.11.0":
+ version: 7.11.0
+ resolution: "@babel/plugin-proposal-optional-chaining@npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-chaining%2Fdownload%2F%40babel%2Fplugin-proposal-optional-chaining-7.11.0.tgz"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.10.4
+ "@babel/helper-skip-transparent-expression-wrappers": ^7.11.0
+ "@babel/plugin-syntax-optional-chaining": ^7.8.0
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: fb59410944f66de515e34eb68a5fa2c530db7f87d2e599230f5d512ebf1d4c92d2e10a39ec012feefc1cc748a3e3b0be25967997bff23af9bb6f7c1402d3eda7
+ languageName: node
+ linkType: hard
+
"@babel/plugin-proposal-private-methods@npm:^7.10.4":
version: 7.10.4
resolution: "@babel/plugin-proposal-private-methods@npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-private-methods%2Fdownload%2F%40babel%2Fplugin-proposal-private-methods-7.10.4.tgz"
@@ -546,6 +684,17 @@ __metadata: languageName: node
linkType: hard
+"@babel/plugin-syntax-export-namespace-from@npm:^7.8.3":
+ version: 7.8.3
+ resolution: "@babel/plugin-syntax-export-namespace-from@npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-export-namespace-from%2Fdownload%2F%40babel%2Fplugin-syntax-export-namespace-from-7.8.3.tgz"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.8.3
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 832e007319bc5040818012d51eb91c3ad4c38a1ea696e9a9805df4d601d8c4f061032cb61494946e7bdaa5db0422a6bb6f39577cd0e5c8323b6bb2c364406dcb
+ languageName: node
+ linkType: hard
+
"@babel/plugin-syntax-json-strings@npm:^7.8.0":
version: 7.8.3
resolution: "@babel/plugin-syntax-json-strings@npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-json-strings%2Fdownload%2F%40babel%2Fplugin-syntax-json-strings-7.8.3.tgz"
@@ -568,6 +717,17 @@ __metadata: languageName: node
linkType: hard
+"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4":
+ version: 7.10.4
+ resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-logical-assignment-operators%2Fdownload%2F%40babel%2Fplugin-syntax-logical-assignment-operators-7.10.4.tgz"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.10.4
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 5b82f717707d278e58d12649932bf3327923361f051cd4517a5b63d7ebfe39cb6cdfb37aa199b5a441db305301a3c8de01c946d25d1f4c4ecb94322a23ac9e73
+ languageName: node
+ linkType: hard
+
"@babel/plugin-syntax-nullish-coalescing-operator@npm:^7.8.0":
version: 7.8.3
resolution: "@babel/plugin-syntax-nullish-coalescing-operator@npm:7.8.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-nullish-coalescing-operator%2Fdownload%2F%40babel%2Fplugin-syntax-nullish-coalescing-operator-7.8.3.tgz"
@@ -1039,6 +1199,18 @@ __metadata: languageName: node
linkType: hard
+"@babel/plugin-transform-spread@npm:^7.11.0":
+ version: 7.11.0
+ resolution: "@babel/plugin-transform-spread@npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-spread%2Fdownload%2F%40babel%2Fplugin-transform-spread-7.11.0.tgz"
+ dependencies:
+ "@babel/helper-plugin-utils": ^7.10.4
+ "@babel/helper-skip-transparent-expression-wrappers": ^7.11.0
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: b10b0608d993441b649160db357161222e9e39afb4fc17c004aa67861cf21bcbfe757099bc68338c5119bc3068d1e4dcd3783fc84d11c5e76134e24e2b5a13a2
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-sticky-regex@npm:^7.10.4":
version: 7.10.4
resolution: "@babel/plugin-transform-sticky-regex@npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-sticky-regex%2Fdownload%2F%40babel%2Fplugin-transform-sticky-regex-7.10.4.tgz"
@@ -1110,7 +1282,85 @@ __metadata: languageName: node
linkType: hard
-"@babel/preset-env@npm:^7.10.2, @babel/preset-env@npm:^7.8.4":
+"@babel/preset-env@npm:^7.11.0":
+ version: 7.11.0
+ resolution: "@babel/preset-env@npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-env%2Fdownload%2F%40babel%2Fpreset-env-7.11.0.tgz"
+ dependencies:
+ "@babel/compat-data": ^7.11.0
+ "@babel/helper-compilation-targets": ^7.10.4
+ "@babel/helper-module-imports": ^7.10.4
+ "@babel/helper-plugin-utils": ^7.10.4
+ "@babel/plugin-proposal-async-generator-functions": ^7.10.4
+ "@babel/plugin-proposal-class-properties": ^7.10.4
+ "@babel/plugin-proposal-dynamic-import": ^7.10.4
+ "@babel/plugin-proposal-export-namespace-from": ^7.10.4
+ "@babel/plugin-proposal-json-strings": ^7.10.4
+ "@babel/plugin-proposal-logical-assignment-operators": ^7.11.0
+ "@babel/plugin-proposal-nullish-coalescing-operator": ^7.10.4
+ "@babel/plugin-proposal-numeric-separator": ^7.10.4
+ "@babel/plugin-proposal-object-rest-spread": ^7.11.0
+ "@babel/plugin-proposal-optional-catch-binding": ^7.10.4
+ "@babel/plugin-proposal-optional-chaining": ^7.11.0
+ "@babel/plugin-proposal-private-methods": ^7.10.4
+ "@babel/plugin-proposal-unicode-property-regex": ^7.10.4
+ "@babel/plugin-syntax-async-generators": ^7.8.0
+ "@babel/plugin-syntax-class-properties": ^7.10.4
+ "@babel/plugin-syntax-dynamic-import": ^7.8.0
+ "@babel/plugin-syntax-export-namespace-from": ^7.8.3
+ "@babel/plugin-syntax-json-strings": ^7.8.0
+ "@babel/plugin-syntax-logical-assignment-operators": ^7.10.4
+ "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.0
+ "@babel/plugin-syntax-numeric-separator": ^7.10.4
+ "@babel/plugin-syntax-object-rest-spread": ^7.8.0
+ "@babel/plugin-syntax-optional-catch-binding": ^7.8.0
+ "@babel/plugin-syntax-optional-chaining": ^7.8.0
+ "@babel/plugin-syntax-top-level-await": ^7.10.4
+ "@babel/plugin-transform-arrow-functions": ^7.10.4
+ "@babel/plugin-transform-async-to-generator": ^7.10.4
+ "@babel/plugin-transform-block-scoped-functions": ^7.10.4
+ "@babel/plugin-transform-block-scoping": ^7.10.4
+ "@babel/plugin-transform-classes": ^7.10.4
+ "@babel/plugin-transform-computed-properties": ^7.10.4
+ "@babel/plugin-transform-destructuring": ^7.10.4
+ "@babel/plugin-transform-dotall-regex": ^7.10.4
+ "@babel/plugin-transform-duplicate-keys": ^7.10.4
+ "@babel/plugin-transform-exponentiation-operator": ^7.10.4
+ "@babel/plugin-transform-for-of": ^7.10.4
+ "@babel/plugin-transform-function-name": ^7.10.4
+ "@babel/plugin-transform-literals": ^7.10.4
+ "@babel/plugin-transform-member-expression-literals": ^7.10.4
+ "@babel/plugin-transform-modules-amd": ^7.10.4
+ "@babel/plugin-transform-modules-commonjs": ^7.10.4
+ "@babel/plugin-transform-modules-systemjs": ^7.10.4
+ "@babel/plugin-transform-modules-umd": ^7.10.4
+ "@babel/plugin-transform-named-capturing-groups-regex": ^7.10.4
+ "@babel/plugin-transform-new-target": ^7.10.4
+ "@babel/plugin-transform-object-super": ^7.10.4
+ "@babel/plugin-transform-parameters": ^7.10.4
+ "@babel/plugin-transform-property-literals": ^7.10.4
+ "@babel/plugin-transform-regenerator": ^7.10.4
+ "@babel/plugin-transform-reserved-words": ^7.10.4
+ "@babel/plugin-transform-shorthand-properties": ^7.10.4
+ "@babel/plugin-transform-spread": ^7.11.0
+ "@babel/plugin-transform-sticky-regex": ^7.10.4
+ "@babel/plugin-transform-template-literals": ^7.10.4
+ "@babel/plugin-transform-typeof-symbol": ^7.10.4
+ "@babel/plugin-transform-unicode-escapes": ^7.10.4
+ "@babel/plugin-transform-unicode-regex": ^7.10.4
+ "@babel/preset-modules": ^0.1.3
+ "@babel/types": ^7.11.0
+ browserslist: ^4.12.0
+ core-js-compat: ^3.6.2
+ invariant: ^2.2.2
+ levenary: ^1.1.1
+ semver: ^5.5.0
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 5ce0e1d188c14c47f3278d39f927e158ec9f66793d04891ad0b066413141f3ba6fffea720cc7408d9e8bce3cc8de63fff07884fd8331ca5c04fbf1fdedb17614
+ languageName: node
+ linkType: hard
+
+"@babel/preset-env@npm:^7.8.4":
version: 7.10.4
resolution: "@babel/preset-env@npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-env%2Fdownload%2F%40babel%2Fpreset-env-7.10.4.tgz"
dependencies:
@@ -1199,7 +1449,7 @@ __metadata: languageName: node
linkType: hard
-"@babel/preset-react@npm:^7.10.1":
+"@babel/preset-react@npm:^7.10.4":
version: 7.10.4
resolution: "@babel/preset-react@npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-react%2Fdownload%2F%40babel%2Fpreset-react-7.10.4.tgz"
dependencies:
@@ -1216,7 +1466,7 @@ __metadata: languageName: node
linkType: hard
-"@babel/preset-typescript@npm:^7.10.1":
+"@babel/preset-typescript@npm:^7.10.4":
version: 7.10.4
resolution: "@babel/preset-typescript@npm:7.10.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-typescript%2Fdownload%2F%40babel%2Fpreset-typescript-7.10.4.tgz"
dependencies:
@@ -1275,6 +1525,23 @@ __metadata: languageName: node
linkType: hard
+"@babel/traverse@npm:^7.11.0":
+ version: 7.11.0
+ resolution: "@babel/traverse@npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftraverse%2Fdownload%2F%40babel%2Ftraverse-7.11.0.tgz"
+ dependencies:
+ "@babel/code-frame": ^7.10.4
+ "@babel/generator": ^7.11.0
+ "@babel/helper-function-name": ^7.10.4
+ "@babel/helper-split-export-declaration": ^7.11.0
+ "@babel/parser": ^7.11.0
+ "@babel/types": ^7.11.0
+ debug: ^4.1.0
+ globals: ^11.1.0
+ lodash: ^4.17.19
+ checksum: 81e4bb3020f18474d873be18c1ff56816c9de1ed38bffb933976b04904c626d2fa9a7c621658360e38c0b125175cc04f4946f19c10f65941632d17fdc4d399dc
+ languageName: node
+ linkType: hard
+
"@babel/types@npm:^7.10.4, @babel/types@npm:^7.10.5, @babel/types@npm:^7.4.4":
version: 7.10.5
resolution: "@babel/types@npm:7.10.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.10.5.tgz"
@@ -1286,6 +1553,17 @@ __metadata: languageName: node
linkType: hard
+"@babel/types@npm:^7.11.0":
+ version: 7.11.0
+ resolution: "@babel/types@npm:7.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.11.0.tgz"
+ dependencies:
+ "@babel/helper-validator-identifier": ^7.10.4
+ lodash: ^4.17.19
+ to-fast-properties: ^2.0.0
+ checksum: 46e2fcd49d1c6d3261fcc3e88906fa39661a193365325ca94b9b1d59f949cef8546e3aba3e13a122b1bf2a493120ad00c06533ae0c428ad60ce81ee2a2649964
+ languageName: node
+ linkType: hard
+
"@csstools/convert-colors@npm:^1.4.0":
version: 1.4.0
resolution: "@csstools/convert-colors@npm:1.4.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40csstools%2Fconvert-colors%2Fdownload%2F%40csstools%2Fconvert-colors-1.4.0.tgz"
@@ -1536,6 +1814,13 @@ __metadata: languageName: node
linkType: hard
+"@types/html-minifier-terser@npm:^5.0.0":
+ version: 5.1.0
+ resolution: "@types/html-minifier-terser@npm:5.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fhtml-minifier-terser%2Fdownload%2F%40types%2Fhtml-minifier-terser-5.1.0.tgz"
+ checksum: e07f30cf9b3bfc3fcf4854c28b43cbdfb9c25180368a393749c762c4b980985037acddef50d894d722bf6e3d866b4c6d6d466ecb3b4db997429e5f75cc8bc422
+ languageName: node
+ linkType: hard
+
"@types/http-cache-semantics@npm:*":
version: 4.0.0
resolution: "@types/http-cache-semantics@npm:4.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fhttp-cache-semantics%2Fdownload%2F%40types%2Fhttp-cache-semantics-4.0.0.tgz"
@@ -1559,10 +1844,10 @@ __metadata: languageName: node
linkType: hard
-"@types/lodash@npm:^4.14.155":
- version: 4.14.157
- resolution: "@types/lodash@npm:4.14.157::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Flodash%2Fdownload%2F%40types%2Flodash-4.14.157.tgz"
- checksum: ea8d890a4d78f4690f9d8e5cb03f3581e8ea59047696e2c2114087ec471e891b3ce683e5344c9c15ea7bd9730b79e5fd808b3eff80a01741503ea59922c2bb83
+"@types/lodash@npm:^4.14.159":
+ version: 4.14.159
+ resolution: "@types/lodash@npm:4.14.159::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Flodash%2Fdownload%2F%40types%2Flodash-4.14.159.tgz"
+ checksum: 15fc1b690916aec2e169327759fbc71b0cb25ca0cd0003c4d20d2e5b4ed14b7bc2feb2835d643e0335eabc1536e7c11b499de591eb794fbb764523cb06c66eee
languageName: node
linkType: hard
@@ -1573,7 +1858,7 @@ __metadata: languageName: node
linkType: hard
-"@types/node@npm:*, @types/node@npm:^14.0.11":
+"@types/node@npm:*":
version: 14.0.23
resolution: "@types/node@npm:14.0.23::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-14.0.23.tgz"
checksum: 35415a294f536c2b14d29ec02a733af23405f4e7e87dace5b4392a69358aae7a14d28805a528b6e9a5f55cfbd9e035bd817e4db0325945fe0332db40ecabdf84
@@ -1587,6 +1872,13 @@ __metadata: languageName: node
linkType: hard
+"@types/node@npm:^14.6.0":
+ version: 14.6.0
+ resolution: "@types/node@npm:14.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-14.6.0.tgz"
+ checksum: ff23553ab77516d0f90b6710a041a49723fc1b1ca33a5379d5746068cac8b9ddbec428d3a4913afaee50bcdc69b9583843740a18a3519ae997982694f5287c6b
+ languageName: node
+ linkType: hard
+
"@types/prop-types@npm:*":
version: 15.7.3
resolution: "@types/prop-types@npm:15.7.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fprop-types%2Fdownload%2F%40types%2Fprop-types-15.7.3.tgz"
@@ -1623,7 +1915,7 @@ __metadata: languageName: node
linkType: hard
-"@types/react-router@npm:*, @types/react-router@npm:^5.1.7":
+"@types/react-router@npm:*, @types/react-router@npm:^5.1.8":
version: 5.1.8
resolution: "@types/react-router@npm:5.1.8::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact-router%2Fdownload%2F%40types%2Freact-router-5.1.8.tgz"
dependencies:
@@ -1633,7 +1925,7 @@ __metadata: languageName: node
linkType: hard
-"@types/react@npm:*, @types/react@npm:^16.9.35":
+"@types/react@npm:*":
version: 16.9.43
resolution: "@types/react@npm:16.9.43::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact%2Fdownload%2F%40types%2Freact-16.9.43.tgz"
dependencies:
@@ -1643,13 +1935,23 @@ __metadata: languageName: node
linkType: hard
-"@types/reactstrap@npm:^8.4.2":
- version: 8.5.0
- resolution: "@types/reactstrap@npm:8.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freactstrap%2Fdownload%2F%40types%2Freactstrap-8.5.0.tgz"
+"@types/react@npm:^16.9.46":
+ version: 16.9.46
+ resolution: "@types/react@npm:16.9.46::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact%2Fdownload%2F%40types%2Freact-16.9.46.tgz"
+ dependencies:
+ "@types/prop-types": "*"
+ csstype: ^3.0.2
+ checksum: ad8d07195dc483f9186dc7886bba15c39e6f9c29bbbd97e52a7a117016f07ac6f923b202749d40833bef62fe60f4af6847b82dcfa0c539495e541ad6d819e49a
+ languageName: node
+ linkType: hard
+
+"@types/reactstrap@npm:^8.5.1":
+ version: 8.5.1
+ resolution: "@types/reactstrap@npm:8.5.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freactstrap%2Fdownload%2F%40types%2Freactstrap-8.5.1.tgz"
dependencies:
"@types/react": "*"
popper.js: ^1.14.1
- checksum: 5c8bf89b4f36480b453c8f5de4a8b073e21c52e87449edfe5cdc329eda7a6e3cbf36779478f5e108b135d4de24398ccafc93487c13c68c0452abae202716118c
+ checksum: 87b383af721243214a3ae8bf4867f932ed0fcd56489337290ce090a264e3db6419ee266d57dcdc406bdbf9185c5cf2c742402e870c396c6735f8ebc00c06af09
languageName: node
linkType: hard
@@ -1678,7 +1980,7 @@ __metadata: languageName: node
linkType: hard
-"@types/tapable@npm:*":
+"@types/tapable@npm:*, @types/tapable@npm:^1.0.5":
version: 1.0.6
resolution: "@types/tapable@npm:1.0.6::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Ftapable%2Fdownload%2F%40types%2Ftapable-1.0.6.tgz"
checksum: 01709a2f8dbea665a39c008ba6995c76210fabb52434815e7632c7fff22ecad1dd49a1d75b8f5b2e9b365c6d7a6407127bed834587df4777b800110c2a74fc36
@@ -1712,7 +2014,7 @@ __metadata: languageName: node
linkType: hard
-"@types/webpack@npm:^4.4.31":
+"@types/webpack@npm:^4.4.31, @types/webpack@npm:^4.41.8":
version: 4.41.21
resolution: "@types/webpack@npm:4.41.21::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fwebpack%2Fdownload%2F%40types%2Fwebpack-4.41.21.tgz"
dependencies:
@@ -1733,11 +2035,11 @@ __metadata: languageName: node
linkType: hard
-"@typescript-eslint/eslint-plugin@npm:^3.6.1":
- version: 3.6.1
- resolution: "@typescript-eslint/eslint-plugin@npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Feslint-plugin%2Fdownload%2F%40typescript-eslint%2Feslint-plugin-3.6.1.tgz"
+"@typescript-eslint/eslint-plugin@npm:^3.9.1":
+ version: 3.9.1
+ resolution: "@typescript-eslint/eslint-plugin@npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Feslint-plugin%2Fdownload%2F%40typescript-eslint%2Feslint-plugin-3.9.1.tgz"
dependencies:
- "@typescript-eslint/experimental-utils": 3.6.1
+ "@typescript-eslint/experimental-utils": 3.9.1
debug: ^4.1.1
functional-red-black-tree: ^1.0.1
regexpp: ^3.0.0
@@ -1750,33 +2052,33 @@ __metadata: peerDependenciesMeta:
typescript:
optional: true
- checksum: eb4c47eb0a2acd7a41ad0f55f3107821e60f77b5cdd37dab53a67fe3a810ac9e9ed3f61b2e53b418fce4f1b43a58feb009abd4f6a66ca24d3ff80f72431ec6fc
+ checksum: 252bab346c02c78f97bc389686230ba0260409f1471c1bea91764ea1ff0aa30d941294c4ae59a4d3f5ca2f8e73311a080709f0d0e5923b9dd4c013b0d9a1f583
languageName: node
linkType: hard
-"@typescript-eslint/experimental-utils@npm:3.6.1":
- version: 3.6.1
- resolution: "@typescript-eslint/experimental-utils@npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fexperimental-utils%2Fdownload%2F%40typescript-eslint%2Fexperimental-utils-3.6.1.tgz"
+"@typescript-eslint/experimental-utils@npm:3.9.1":
+ version: 3.9.1
+ resolution: "@typescript-eslint/experimental-utils@npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fexperimental-utils%2Fdownload%2F%40typescript-eslint%2Fexperimental-utils-3.9.1.tgz"
dependencies:
"@types/json-schema": ^7.0.3
- "@typescript-eslint/types": 3.6.1
- "@typescript-eslint/typescript-estree": 3.6.1
+ "@typescript-eslint/types": 3.9.1
+ "@typescript-eslint/typescript-estree": 3.9.1
eslint-scope: ^5.0.0
eslint-utils: ^2.0.0
peerDependencies:
eslint: "*"
- checksum: dd8bd15c205562f37fb5e5f0981f6a8d93c8dede48f96467063e9404a2ae36f801c5370963b18c4101d71de12b8b003bc1ed57c3d79f7c76489a74a58811737f
+ checksum: 8092e411ad2b8c57bb848507f9feffd7c305ca469b494b3d97b4176b73f0d9dbff20715a66537e9916a17b9aff9d76c446a0849967712bac2fba9b237f3df395
languageName: node
linkType: hard
-"@typescript-eslint/parser@npm:^3.6.1":
- version: 3.6.1
- resolution: "@typescript-eslint/parser@npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fparser%2Fdownload%2F%40typescript-eslint%2Fparser-3.6.1.tgz"
+"@typescript-eslint/parser@npm:^3.9.1":
+ version: 3.9.1
+ resolution: "@typescript-eslint/parser@npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fparser%2Fdownload%2F%40typescript-eslint%2Fparser-3.9.1.tgz"
dependencies:
"@types/eslint-visitor-keys": ^1.0.0
- "@typescript-eslint/experimental-utils": 3.6.1
- "@typescript-eslint/types": 3.6.1
- "@typescript-eslint/typescript-estree": 3.6.1
+ "@typescript-eslint/experimental-utils": 3.9.1
+ "@typescript-eslint/types": 3.9.1
+ "@typescript-eslint/typescript-estree": 3.9.1
eslint-visitor-keys: ^1.1.0
peerDependencies:
eslint: ^5.0.0 || ^6.0.0 || ^7.0.0
@@ -1784,23 +2086,23 @@ __metadata: peerDependenciesMeta:
typescript:
optional: true
- checksum: 0fbb334ab4c689b52cf39e1b50468ea27d99c9f6e6bea5711091dd296b42a51317aca9c17a75535226311aa94419fc39d5241948512d2ccf8cc5f80c924e9f9c
+ checksum: ed9a4829697cb02b18d47b83d8bb5678f37a5eb996e47ded58387dda22f0b6e51800f0a3ecf6136f23827bfc654cd0f38d5082ca66a93c593ee0afa370edcc10
languageName: node
linkType: hard
-"@typescript-eslint/types@npm:3.6.1":
- version: 3.6.1
- resolution: "@typescript-eslint/types@npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypes%2Fdownload%2F%40typescript-eslint%2Ftypes-3.6.1.tgz"
- checksum: c90e36b62375a20a40b2a971a6fd60c27f606bf80a65649e765c837b4d5cc6aaad012d4356fbadcc051d9e07678aa045b62dbae78b9fe65dc8c8b0e2acc0abad
+"@typescript-eslint/types@npm:3.9.1":
+ version: 3.9.1
+ resolution: "@typescript-eslint/types@npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypes%2Fdownload%2F%40typescript-eslint%2Ftypes-3.9.1.tgz"
+ checksum: 0591ff76919fb8d19af26f0657329d8fa499484f64e073a76ae2f846ea39074c3cd888ae185d16aa2974eb1ca3a0aa6083040c13872a2aaafb8a10e1b8a38a9e
languageName: node
linkType: hard
-"@typescript-eslint/typescript-estree@npm:3.6.1":
- version: 3.6.1
- resolution: "@typescript-eslint/typescript-estree@npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypescript-estree%2Fdownload%2F%40typescript-eslint%2Ftypescript-estree-3.6.1.tgz"
+"@typescript-eslint/typescript-estree@npm:3.9.1":
+ version: 3.9.1
+ resolution: "@typescript-eslint/typescript-estree@npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Ftypescript-estree%2Fdownload%2F%40typescript-eslint%2Ftypescript-estree-3.9.1.tgz"
dependencies:
- "@typescript-eslint/types": 3.6.1
- "@typescript-eslint/visitor-keys": 3.6.1
+ "@typescript-eslint/types": 3.9.1
+ "@typescript-eslint/visitor-keys": 3.9.1
debug: ^4.1.1
glob: ^7.1.6
is-glob: ^4.0.1
@@ -1812,16 +2114,16 @@ __metadata: peerDependenciesMeta:
typescript:
optional: true
- checksum: 93eef4a7ac59c38bdeb93cacd5d93cffbcf4fee369cca24614edf0557e0a01d5e31059da5ca8f58cf94504965432ba4ede3a7a724f9db88527bec3cf85d9111a
+ checksum: f9a962b6ffd557aff680ccc8a67e79e305002dd90f7637f0d22b9e6e9112dc143f629d12af769e6252c17025cc4bc381218a425fdb4bf9dbd8c12a235356d8c1
languageName: node
linkType: hard
-"@typescript-eslint/visitor-keys@npm:3.6.1":
- version: 3.6.1
- resolution: "@typescript-eslint/visitor-keys@npm:3.6.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fvisitor-keys%2Fdownload%2F%40typescript-eslint%2Fvisitor-keys-3.6.1.tgz"
+"@typescript-eslint/visitor-keys@npm:3.9.1":
+ version: 3.9.1
+ resolution: "@typescript-eslint/visitor-keys@npm:3.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40typescript-eslint%2Fvisitor-keys%2Fdownload%2F%40typescript-eslint%2Fvisitor-keys-3.9.1.tgz"
dependencies:
eslint-visitor-keys: ^1.1.0
- checksum: 041b3af065e5cb1a7a53bf17a684372a0388bad63de80854ac9c32dccbd46f9c822ca69d33622db2e4583506a4baa74fab9ef67687d435ac073077ae870067e5
+ checksum: 9e54d3a37aef8c177872dcfba59ead2de6bd5c7370a735dc5965d499ca7d93cef6edf297bc07f114098291e797b561cae1bbc74e3e426a3c521d02f03cef95e0
languageName: node
linkType: hard
@@ -2571,12 +2873,12 @@ __metadata: languageName: node
linkType: hard
-"axios@npm:^0.19.2":
- version: 0.19.2
- resolution: "axios@npm:0.19.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.19.2.tgz"
+"axios@npm:^0.20.0":
+ version: 0.20.0
+ resolution: "axios@npm:0.20.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.20.0.tgz"
dependencies:
- follow-redirects: 1.5.10
- checksum: bad346deea24050f9953ce09bb8015f85a99a7b8f016806adccfab0b8981827d1fbee9c77c0ef7c70cc48392c1af6bbc65e07c3e88221d17282d2d5fd0a191f6
+ follow-redirects: ^1.10.0
+ checksum: 6cf2e963176a0d18fc457d7cb71cb6cf552193619b161fc61070d9a4db3a26a87ecfe760ba36e7af174c05a6a9898dc52cfeb5c0e62e19fddd9788739553ad73
languageName: node
linkType: hard
@@ -2774,13 +3076,6 @@ __metadata: languageName: node
linkType: hard
-"big.js@npm:^3.1.3":
- version: 3.2.0
- resolution: "big.js@npm:3.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbig.js%2Fdownload%2Fbig.js-3.2.0.tgz"
- checksum: 6f08a28dd4501758ec069301182763f847633c6bc63b04714547c8b85b4b6e1d5772901370a8fca1f7d82f1ca9b2b9165ebbf397b46d9e05fbd84b9b06556999
- languageName: node
- linkType: hard
-
"big.js@npm:^5.2.2":
version: 5.2.2
resolution: "big.js@npm:5.2.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbig.js%2Fdownload%2Fbig.js-5.2.2.tgz"
@@ -2871,20 +3166,20 @@ __metadata: languageName: node
linkType: hard
-"bootstrap-icons@npm:^1.0.0-alpha4":
+"bootstrap-icons@npm:^1.0.0-alpha5":
version: 1.0.0-alpha5
resolution: "bootstrap-icons@npm:1.0.0-alpha5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbootstrap-icons%2Fdownload%2Fbootstrap-icons-1.0.0-alpha5.tgz"
checksum: a97c110bc9bc4ad7497eb2d9b6424a684930a35a0eaddd4577589b97c5efcce52d37270feb372394885d9a81934cf4cb9ece10d7d0c23adaa7fd9e3e86cf74e3
languageName: node
linkType: hard
-"bootstrap@npm:^4.5.0":
- version: 4.5.0
- resolution: "bootstrap@npm:4.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbootstrap%2Fdownload%2Fbootstrap-4.5.0.tgz"
+"bootstrap@npm:^4.5.2":
+ version: 4.5.2
+ resolution: "bootstrap@npm:4.5.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fbootstrap%2Fdownload%2Fbootstrap-4.5.2.tgz"
peerDependencies:
jquery: 1.9.1 - 3
- popper.js: ^1.16.0
- checksum: 89284a8d1bfcf508588e2eedb652374af5790d2b47d3ca7b192ec67742db99c9652181979a6ab16b91230df1efea1a8ac5a4e6ffd44265a7b5f0583d275227d3
+ popper.js: ^1.16.1
+ checksum: 980e7e4ebd1ba50b605a8f22e2b80cb024db23b5fb7790ff54bc3cd9345496610f36028fa14c78a50a50e1026a977aeaa60245211144f4fbf9d3eb3cd6949760
languageName: node
linkType: hard
@@ -3212,13 +3507,13 @@ __metadata: languageName: node
linkType: hard
-"camel-case@npm:3.0.x":
- version: 3.0.0
- resolution: "camel-case@npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamel-case%2Fdownload%2Fcamel-case-3.0.0.tgz"
+"camel-case@npm:^4.1.1":
+ version: 4.1.1
+ resolution: "camel-case@npm:4.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamel-case%2Fdownload%2Fcamel-case-4.1.1.tgz"
dependencies:
- no-case: ^2.2.0
- upper-case: ^1.1.1
- checksum: 1cfcf1eb9725b6e61d3b4b996bd521aa4a4b86c9022d2df2c960e451b557eee259505066a9d6d172f2b38fb7bed07c9d07b08aa645bed5c66f92b5372495cb9f
+ pascal-case: ^3.1.1
+ tslib: ^1.10.0
+ checksum: c202f62a74c020e51ab6d7d02c0367a6b8cd5d1803e69371421970186d6ca32a20437eb45257baa00a7bb976a202e8fbdb75d509145f5b022f7f80936997c6b8
languageName: node
linkType: hard
@@ -3229,6 +3524,13 @@ __metadata: languageName: node
linkType: hard
+"camelcase@npm:^6.0.0":
+ version: 6.0.0
+ resolution: "camelcase@npm:6.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamelcase%2Fdownload%2Fcamelcase-6.0.0.tgz"
+ checksum: d92305180bc2041141cc0c889ee54d14f90b16365dc7c01eabe6d54e913eb8011313f98dde3025ae11f0003b601ba320f56ee56db476c64060cf2305bf7f6f2a
+ languageName: node
+ linkType: hard
+
"caniuse-lite@npm:^1.0.30000981, caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001111":
version: 1.0.30001117
resolution: "caniuse-lite@npm:1.0.30001117::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcaniuse-lite%2Fdownload%2Fcaniuse-lite-1.0.30001117.tgz"
@@ -3294,7 +3596,7 @@ __metadata: languageName: node
linkType: hard
-"chokidar@npm:>=2.0.0 <4.0.0, chokidar@npm:^3.4.0":
+"chokidar@npm:>=2.0.0 <4.0.0, chokidar@npm:^3.4.1":
version: 3.4.1
resolution: "chokidar@npm:3.4.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fchokidar%2Fdownload%2Fchokidar-3.4.1.tgz"
dependencies:
@@ -3395,7 +3697,7 @@ __metadata: languageName: node
linkType: hard
-"clean-css@npm:4.2.x":
+"clean-css@npm:^4.2.3":
version: 4.2.3
resolution: "clean-css@npm:4.2.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fclean-css%2Fdownload%2Fclean-css-4.2.3.tgz"
dependencies:
@@ -3529,13 +3831,6 @@ __metadata: languageName: node
linkType: hard
-"commander@npm:2.17.x":
- version: 2.17.1
- resolution: "commander@npm:2.17.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.17.1.tgz"
- checksum: 017ef909a7871e0865879bf90cca0527c920010fe5a222b55ba7205baa1d336ea868b7dde4a060c8fc1ede85a1325cc79eef5e1f21170ac626d2ece82a58ad73
- languageName: node
- linkType: hard
-
"commander@npm:^2.20.0":
version: 2.20.3
resolution: "commander@npm:2.20.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.20.3.tgz"
@@ -3543,10 +3838,10 @@ __metadata: languageName: node
linkType: hard
-"commander@npm:~2.19.0":
- version: 2.19.0
- resolution: "commander@npm:2.19.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.19.0.tgz"
- checksum: 1a18c37b383203c02667a9307c882e966e45f923e1052cc3d799f4007cce51fdc82ffe4c2b1ec2946cded7b3856e7a6e1c048d5d0ab906c8b8014d6ce172db19
+"commander@npm:^4.1.1":
+ version: 4.1.1
+ resolution: "commander@npm:4.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-4.1.1.tgz"
+ checksum: 448585071bf8fb4c0bf9dd52abaee43dea086f801334caec2c8e8c9f456f8abc224c1614ccbbdbf7da5ac2524d230f13cf1fc86c233cf8a041ebecea7df106e9
languageName: node
linkType: hard
@@ -3714,7 +4009,7 @@ __metadata: languageName: node
linkType: hard
-"copy-webpack-plugin@npm:^6.0.2":
+"copy-webpack-plugin@npm:^6.0.3":
version: 6.0.3
resolution: "copy-webpack-plugin@npm:6.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcopy-webpack-plugin%2Fdownload%2Fcopy-webpack-plugin-6.0.3.tgz"
dependencies:
@@ -3922,26 +4217,26 @@ __metadata: languageName: node
linkType: hard
-"css-loader@npm:^3.5.3":
- version: 3.6.0
- resolution: "css-loader@npm:3.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-loader%2Fdownload%2Fcss-loader-3.6.0.tgz"
+"css-loader@npm:^4.2.1":
+ version: 4.2.1
+ resolution: "css-loader@npm:4.2.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-loader%2Fdownload%2Fcss-loader-4.2.1.tgz"
dependencies:
- camelcase: ^5.3.1
+ camelcase: ^6.0.0
cssesc: ^3.0.0
icss-utils: ^4.1.1
- loader-utils: ^1.2.3
+ loader-utils: ^2.0.0
normalize-path: ^3.0.0
postcss: ^7.0.32
postcss-modules-extract-imports: ^2.0.0
- postcss-modules-local-by-default: ^3.0.2
+ postcss-modules-local-by-default: ^3.0.3
postcss-modules-scope: ^2.2.0
postcss-modules-values: ^3.0.0
postcss-value-parser: ^4.1.0
schema-utils: ^2.7.0
- semver: ^6.3.0
+ semver: ^7.3.2
peerDependencies:
- webpack: ^4.0.0 || ^5.0.0
- checksum: f916e1dc6914e9fda52e81e603e5afd8cf68c866d9d1cb84edf245fa3ce6bec4252be841edc694c8f6aeb855c94dbde1baccb44678f0b652bbb8fb7ca68a1a0a
+ webpack: ^4.27.0 || ^5.0.0
+ checksum: bd8188efac141352371d3c87e90b6c5658018fa2e9438a22ad38e7a3896e492edb535ae7fe7e56e4c14e43ccc88fbb3a235a0929d4f9302bbf12215687edc9fa
languageName: node
linkType: hard
@@ -4014,6 +4309,13 @@ __metadata: languageName: node
linkType: hard
+"csstype@npm:^3.0.2":
+ version: 3.0.2
+ resolution: "csstype@npm:3.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcsstype%2Fdownload%2Fcsstype-3.0.2.tgz"
+ checksum: acf2852a3c5f5e1ed84e36526e41584e09353ee57b9bd93bf17f91bd2be60545adaf86c4439b84952d1f596149e06f9da6bb28c1d1ab883c9b2ad68e143e79f4
+ languageName: node
+ linkType: hard
+
"cyclist@npm:^1.0.1":
version: 1.0.1
resolution: "cyclist@npm:1.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcyclist%2Fdownload%2Fcyclist-1.0.1.tgz"
@@ -4399,6 +4701,16 @@ __metadata: languageName: node
linkType: hard
+"dot-case@npm:^3.0.3":
+ version: 3.0.3
+ resolution: "dot-case@npm:3.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdot-case%2Fdownload%2Fdot-case-3.0.3.tgz"
+ dependencies:
+ no-case: ^3.0.3
+ tslib: ^1.10.0
+ checksum: 31e5037039fb696ed7f1da1d3f0cea5fa0ffe0523334229a2f241856411fbbb59a5a7a6f8ae1447820718797708650bd6f90836d510ec27a81694fbc006c946a
+ languageName: node
+ linkType: hard
+
"duplexify@npm:^3.4.2, duplexify@npm:^3.6.0":
version: 3.7.1
resolution: "duplexify@npm:3.7.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fduplexify%2Fdownload%2Fduplexify-3.7.1.tgz"
@@ -4485,13 +4797,6 @@ __metadata: languageName: node
linkType: hard
-"emojis-list@npm:^2.0.0":
- version: 2.1.0
- resolution: "emojis-list@npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Femojis-list%2Fdownload%2Femojis-list-2.1.0.tgz"
- checksum: 09220b636cb03b16c234b6412391c9d8ce6fab4213659fd88d98a83e1b8fce8c60352f4dfc395a2f14159f1ed348a150c26123aee8afccb15b9747e26ed7b6ec
- languageName: node
- linkType: hard
-
"emojis-list@npm:^3.0.0":
version: 3.0.0
resolution: "emojis-list@npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Femojis-list%2Fdownload%2Femojis-list-3.0.0.tgz"
@@ -4524,7 +4829,7 @@ __metadata: languageName: node
linkType: hard
-"enhanced-resolve@npm:^4.0.0, enhanced-resolve@npm:^4.1.0, enhanced-resolve@npm:^4.1.1":
+"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"
dependencies:
@@ -4649,7 +4954,7 @@ __metadata: languageName: node
linkType: hard
-"eslint-plugin-prettier@npm:^3.1.3":
+"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"
dependencies:
@@ -4661,18 +4966,18 @@ __metadata: languageName: node
linkType: hard
-"eslint-plugin-react-hooks@npm:^4.0.8":
- version: 4.0.8
- resolution: "eslint-plugin-react-hooks@npm:4.0.8::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-react-hooks%2Fdownload%2Feslint-plugin-react-hooks-4.0.8.tgz"
+"eslint-plugin-react-hooks@npm:^4.1.0":
+ version: 4.1.0
+ resolution: "eslint-plugin-react-hooks@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"
peerDependencies:
eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
- checksum: 6e6ce44f1f5981fd07d921bf4e2142183a2670bbd51d7fd41c2ae9b8f117b5c8da8bb6b4db2d092e29e698b026987ead53634e5a4d308a67c32e5127ab7fa73f
+ checksum: 7ef1a971b2eb499cdad118f6b6d504e22e2e46bec6a815dd4c4eae0d8db7fe8a6cbbdd5e6dd94f44a7a09fad61e92e44c8dc0fe0de6ec56356bea9414d2e258a
languageName: node
linkType: hard
-"eslint-plugin-react@npm:^7.20.0":
- version: 7.20.3
- resolution: "eslint-plugin-react@npm:7.20.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-react%2Fdownload%2Feslint-plugin-react-7.20.3.tgz"
+"eslint-plugin-react@npm:^7.20.6":
+ version: 7.20.6
+ resolution: "eslint-plugin-react@npm:7.20.6::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-react%2Fdownload%2Feslint-plugin-react-7.20.6.tgz"
dependencies:
array-includes: ^3.1.1
array.prototype.flatmap: ^1.2.3
@@ -4687,7 +4992,7 @@ __metadata: string.prototype.matchall: ^4.0.2
peerDependencies:
eslint: ^3 || ^4 || ^5 || ^6 || ^7
- checksum: 00b1e5045e490515bf79912d8658cc9bba5f299a07df29e2dc4c643c15f821132a6fdade7b7525882dcf8ee37ecf1b3f93f23ad413f1bcce8b09f62e46264e09
+ checksum: e962f31c322f9b1a41187ef20c0c59cb0ca4185959d8a5345132512cc041d760d25fc6576e5763b86fcc01cb8918328400b793b184035384650b22e02c6f2c24
languageName: node
linkType: hard
@@ -4727,9 +5032,9 @@ __metadata: languageName: node
linkType: hard
-"eslint@npm:^7.2.0":
- version: 7.5.0
- resolution: "eslint@npm:7.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.5.0.tgz"
+"eslint@npm:^7.7.0":
+ version: 7.7.0
+ resolution: "eslint@npm:7.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.7.0.tgz"
dependencies:
"@babel/code-frame": ^7.0.0
ajv: ^6.10.0
@@ -4769,7 +5074,7 @@ __metadata: v8-compile-cache: ^2.0.3
bin:
eslint: bin/eslint.js
- checksum: 5a65f133db997f39e48082636496e11db168c7385839111b2ecbb9d4fa16d9eaeae9a88f0317ddcc5118fe388c2907ab0f302c752fb36e56ace6e3660070ea42
+ checksum: 6f47e20ec67a8ad58ed79ad350373142fb30387f4b9847f43943d80a2307e74252ea8739a9f53ec850ef5eaf689103c3d7b8bbc71e04e06444687cfda51fe3b7
languageName: node
linkType: hard
@@ -5249,7 +5554,7 @@ __metadata: languageName: node
linkType: hard
-"follow-redirects@npm:1.5.10, follow-redirects@npm:^1.0.0":
+"follow-redirects@npm:^1.0.0":
version: 1.5.10
resolution: "follow-redirects@npm:1.5.10::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.5.10.tgz"
dependencies:
@@ -5258,6 +5563,13 @@ __metadata: languageName: node
linkType: hard
+"follow-redirects@npm:^1.10.0":
+ version: 1.13.0
+ resolution: "follow-redirects@npm:1.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.13.0.tgz"
+ checksum: f220828d3f153da30ea616fdbe9f6676e74e4e68c51d336a751037c1d556e2de34aa5918f58951fa19bb6517c9c88b4403a0a8bdfc40d3e779d37def2ac0f2c4
+ languageName: node
+ linkType: hard
+
"for-in@npm:^1.0.2":
version: 1.0.2
resolution: "for-in@npm:1.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffor-in%2Fdownload%2Ffor-in-1.0.2.tgz"
@@ -5824,7 +6136,7 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"he@npm:1.2.x, he@npm:^1.1.1":
+"he@npm:^1.1.1, he@npm:^1.2.0":
version: 1.2.0
resolution: "he@npm:1.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhe%2Fdownload%2Fhe-1.2.0.tgz"
bin:
@@ -5895,20 +6207,20 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"html-minifier@npm:^3.2.3":
- version: 3.5.21
- resolution: "html-minifier@npm:3.5.21::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-minifier%2Fdownload%2Fhtml-minifier-3.5.21.tgz"
- dependencies:
- camel-case: 3.0.x
- clean-css: 4.2.x
- commander: 2.17.x
- he: 1.2.x
- param-case: 2.1.x
- relateurl: 0.2.x
- uglify-js: 3.4.x
+"html-minifier-terser@npm:^5.0.1":
+ version: 5.1.1
+ resolution: "html-minifier-terser@npm:5.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-minifier-terser%2Fdownload%2Fhtml-minifier-terser-5.1.1.tgz"
+ dependencies:
+ camel-case: ^4.1.1
+ clean-css: ^4.2.3
+ commander: ^4.1.1
+ he: ^1.2.0
+ param-case: ^3.0.3
+ relateurl: ^0.2.7
+ terser: ^4.6.3
bin:
- html-minifier: ./cli.js
- checksum: c392d2128c7d2f7de9d44fedcae1e899f3825eb7792c90ca55ab07129b89d0a005fa4f898b6bf73a7f0526d3ff827898c2065cccd53c7f00d45b386ddb8821bf
+ html-minifier-terser: cli.js
+ checksum: d05dea891f5977a35691306b1fb40438cffd6620c2f5a69d7ecb67bfa836af1d36c24978edd1616dc6d27e230561bd756c5f11b3054e6ebf2f8448289e3ca73d
languageName: node
linkType: hard
@@ -5921,20 +6233,22 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"html-webpack-plugin@npm:^3.2.0":
- version: 3.2.0
- resolution: "html-webpack-plugin@npm:3.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-webpack-plugin%2Fdownload%2Fhtml-webpack-plugin-3.2.0.tgz"
+"html-webpack-plugin@npm:^4.3.0":
+ version: 4.3.0
+ resolution: "html-webpack-plugin@npm:4.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-webpack-plugin%2Fdownload%2Fhtml-webpack-plugin-4.3.0.tgz"
dependencies:
- html-minifier: ^3.2.3
- loader-utils: ^0.2.16
- lodash: ^4.17.3
- pretty-error: ^2.0.2
- tapable: ^1.0.0
- toposort: ^1.0.0
+ "@types/html-minifier-terser": ^5.0.0
+ "@types/tapable": ^1.0.5
+ "@types/webpack": ^4.41.8
+ html-minifier-terser: ^5.0.1
+ loader-utils: ^1.2.3
+ lodash: ^4.17.15
+ pretty-error: ^2.1.1
+ tapable: ^1.1.3
util.promisify: 1.0.0
peerDependencies:
- webpack: ^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0
- checksum: 02dcb274a8984442cb164de8920ee0c0a840a494b65c7ff2a1c39f9b687abf668d6a3ff21b693e9f5db8f93cef411c281d74dfd7db956490d51d50d25d64e468
+ webpack: ">=4.0.0 < 6.0.0"
+ checksum: 13c23547ac83142f2e23a993a82e6fa6beb21291848a856c09d27e0dae12f5781699ed9c1fe798fb03cf317a6a4dce164d224fd6023640abc167f222b59a0fa0
languageName: node
linkType: hard
@@ -6083,21 +6397,21 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"i18next-browser-languagedetector@npm:^5.0.0":
- version: 5.0.0
- resolution: "i18next-browser-languagedetector@npm:5.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next-browser-languagedetector%2Fdownload%2Fi18next-browser-languagedetector-5.0.0.tgz"
+"i18next-browser-languagedetector@npm:^6.0.1":
+ version: 6.0.1
+ resolution: "i18next-browser-languagedetector@npm:6.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next-browser-languagedetector%2Fdownload%2Fi18next-browser-languagedetector-6.0.1.tgz"
dependencies:
"@babel/runtime": ^7.5.5
- checksum: 0304f0469d795f11d4615e45d804a04a5ac41bfaac18a8354862f9ee7f27b9b5457d5e6037bd6e0ebf7c3349fcff6333e530674cc93cfd618799e9ec36d0db93
+ checksum: 760bc83f3bfdf18622a55d732c295130fb9d496e5a1ce389820dd253a3b53f4179826da9cb1b915167ff33c25fc33b5bd93bae8157135c026cd91d0e3a1df4fc
languageName: node
linkType: hard
-"i18next@npm:^19.6.2":
- version: 19.6.2
- resolution: "i18next@npm:19.6.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next%2Fdownload%2Fi18next-19.6.2.tgz"
+"i18next@npm:^19.7.0":
+ version: 19.7.0
+ resolution: "i18next@npm:19.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fi18next%2Fdownload%2Fi18next-19.7.0.tgz"
dependencies:
"@babel/runtime": ^7.10.1
- checksum: 50bef70b0e83893701e8a4d233c7a80d84b462fa64d5747b14d7d4f849c4d4d5f3c9a3c5686f9b9942b8dac76b1cba37d6bf7bb5eb23d4d0d72b03658d7bfd15
+ checksum: 7f6fa6576c64c3a89b5228ef69a6229ddcb6aa2ec7a20375f0663c4fb4ead5442d9ef00e59053f6c73b2665df990a75e0fd446e0e2a5b640d92662a109f19734
languageName: node
linkType: hard
@@ -6822,15 +7136,6 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"json5@npm:^0.5.0":
- version: 0.5.1
- resolution: "json5@npm:0.5.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson5%2Fdownload%2Fjson5-0.5.1.tgz"
- bin:
- json5: lib/cli.js
- checksum: 002ce9e56c4159e5a62fc4891dc2fba1fdc077fba417042e9dd54f8c37da80c0274feb5fa4c0acb3efbc8906d5763b4ff292d512269e1951967d530130bd80b8
- languageName: node
- linkType: hard
-
"json5@npm:^1.0.1":
version: 1.0.1
resolution: "json5@npm:1.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson5%2Fdownload%2Fjson5-1.0.1.tgz"
@@ -6935,7 +7240,7 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"klona@npm:^1.1.1":
+"klona@npm:^1.1.2":
version: 1.1.2
resolution: "klona@npm:1.1.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fklona%2Fdownload%2Fklona-1.1.2.tgz"
checksum: 357ff7d43ca2dbaacda91c37bea559642a128e583a2836c09c252881dd71d054d97e7185e91a899ebd65e2b76f7d4e25ca3d06fd0a0b51a5304586d00157a06d
@@ -6984,18 +7289,6 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"loader-utils@npm:^0.2.16":
- version: 0.2.17
- resolution: "loader-utils@npm:0.2.17::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-utils%2Fdownload%2Floader-utils-0.2.17.tgz"
- dependencies:
- big.js: ^3.1.3
- emojis-list: ^2.0.0
- json5: ^0.5.0
- object-assign: ^4.0.1
- checksum: aae13ef9f1f67290ac6bf401e3b250f192b96ee023729e3a8cb140a2cb2e8edb02eca5531c9a789f888878bb510ca3ee2b6a204008a712a893df73b76746eaad
- languageName: node
- linkType: hard
-
"loader-utils@npm:^1.0.2, loader-utils@npm:^1.1.0, loader-utils@npm:^1.2.3, loader-utils@npm:^1.4.0":
version: 1.4.0
resolution: "loader-utils@npm:1.4.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-utils%2Fdownload%2Floader-utils-1.4.0.tgz"
@@ -7018,12 +7311,12 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"localforage@npm:^1.7.4":
- version: 1.7.4
- resolution: "localforage@npm:1.7.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocalforage%2Fdownload%2Flocalforage-1.7.4.tgz"
+"localforage@npm:^1.9.0":
+ version: 1.9.0
+ resolution: "localforage@npm:1.9.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocalforage%2Fdownload%2Flocalforage-1.9.0.tgz"
dependencies:
lie: 3.1.1
- checksum: 81815ccb02bb1e076d3265949a20c3bf2b2890f6124168af24ce21f6c6cc1819b70bb9cfd17d798f4690e761110769a805257d35580f2b77301f1aa2c47cca09
+ checksum: 0645f5ec6fe28799081a9a21dc23796fbb665dcc20e09061228302750a05671bd13a42688e41b523f1598fff5d8e219f468d826595b75db07b555d4ff223943e
languageName: node
linkType: hard
@@ -7072,13 +7365,20 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.3, lodash@npm:^4.17.4":
+"lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.4":
version: 4.17.19
resolution: "lodash@npm:4.17.19::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.19.tgz"
checksum: ff2b7a95f0129dba9101e346d44e0eda0f159d76bbbf23721eec1969b87a32bde3de0cfef0733218c64620e9be08040a973278d46a686540233b356115f3527c
languageName: node
linkType: hard
+"lodash@npm:^4.17.20":
+ version: 4.17.20
+ resolution: "lodash@npm:4.17.20::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.20.tgz"
+ checksum: c62101d2500c383b5f174a7e9e6fe8098149ddd6e9ccfa85f36d4789446195f5c4afd3cfba433026bcaf3da271256566b04a2bf2618e5a39f6e67f8c12030cb6
+ languageName: node
+ linkType: hard
+
"logic-solver@npm:^2.0.1":
version: 2.0.1
resolution: "logic-solver@npm:2.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flogic-solver%2Fdownload%2Flogic-solver-2.0.1.tgz"
@@ -7106,10 +7406,12 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"lower-case@npm:^1.1.1":
- version: 1.1.4
- resolution: "lower-case@npm:1.1.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flower-case%2Fdownload%2Flower-case-1.1.4.tgz"
- checksum: 8150698ed173d76efb8667cf2038dde17d9df93422e83815f1b579da4fd0d46bbed3b9f42487d1902272973c6c2c0b5ecccc628b40b8f301fa9ac3246ab8a253
+"lower-case@npm:^2.0.1":
+ version: 2.0.1
+ resolution: "lower-case@npm:2.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flower-case%2Fdownload%2Flower-case-2.0.1.tgz"
+ dependencies:
+ tslib: ^1.10.0
+ checksum: 52a55327ea69cbec7693daa11efb94f9e3d13b2697773d3cecd71f68c7eafaca2b0b34f8cc10617a751134e17c8396be992972765f5d5db220047651046762b5
languageName: node
linkType: hard
@@ -7623,7 +7925,7 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"neo-async@npm:^2.5.0, neo-async@npm:^2.6.1":
+"neo-async@npm:^2.5.0, neo-async@npm:^2.6.1, neo-async@npm:^2.6.2":
version: 2.6.2
resolution: "neo-async@npm:2.6.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fneo-async%2Fdownload%2Fneo-async-2.6.2.tgz"
checksum: 34a8f5309135be258a97082af810ea43700a3e0121e7b1ea31b3e22e2663d7c0d502cd949abb6d1ab8c11abfd04500ee61721ec5408b2d4bef8105241fd8a4c2
@@ -7637,12 +7939,13 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"no-case@npm:^2.2.0":
- version: 2.3.2
- resolution: "no-case@npm:2.3.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fno-case%2Fdownload%2Fno-case-2.3.2.tgz"
+"no-case@npm:^3.0.3":
+ version: 3.0.3
+ resolution: "no-case@npm:3.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fno-case%2Fdownload%2Fno-case-3.0.3.tgz"
dependencies:
- lower-case: ^1.1.1
- checksum: b4206dd12c6c02743a6e530f4c9439d51f4c4e75d307b8682d9a07f8d5e3662acc204ab5f64f83f725ed1a2a854f90a1bf5fd25fa7f442f82488e1391e4249b3
+ lower-case: ^2.0.1
+ tslib: ^1.10.0
+ checksum: 619e0bd00a3ef0fa6ad9442d32c88adcf47339c5b0d9bdfaaab19380709dad5ba71f865ae584531988ba85a6083e1f0ea0b851bcc49c67aee40a5100104e84b9
languageName: node
linkType: hard
@@ -8163,12 +8466,13 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"param-case@npm:2.1.x":
- version: 2.1.1
- resolution: "param-case@npm:2.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fparam-case%2Fdownload%2Fparam-case-2.1.1.tgz"
+"param-case@npm:^3.0.3":
+ version: 3.0.3
+ resolution: "param-case@npm:3.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fparam-case%2Fdownload%2Fparam-case-3.0.3.tgz"
dependencies:
- no-case: ^2.2.0
- checksum: 2983386706e6c62205a5bc53f172c4393d21c2eb93e2779ae34cf26771498ea5f12464c7642834f4ea7c938dc49ef2e3d7b3d7f7ed393b7f88874cd7793e5462
+ dot-case: ^3.0.3
+ tslib: ^1.10.0
+ checksum: ef57facfaf282f6c074e565e26738e7bb043882aea9a4a575b0568d74f003ab8a1c69555d81773d25413287f079a367aa26a9518b3d5b25f2f17b4952a647f40
languageName: node
linkType: hard
@@ -8219,6 +8523,16 @@ fsevents@~2.1.2: languageName: node
linkType: hard
+"pascal-case@npm:^3.1.1":
+ version: 3.1.1
+ resolution: "pascal-case@npm:3.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpascal-case%2Fdownload%2Fpascal-case-3.1.1.tgz"
+ dependencies:
+ no-case: ^3.0.3
+ tslib: ^1.10.0
+ checksum: 56f66aea7f8c06f3e8b9e70c48c3019dcd8c3e5f218be905b4aba84c5880baf58dcb517bbf1becac3628e17c09b6c3bd35428a9e519343e5f04e50dd0d17c5f5
+ languageName: node
+ linkType: hard
+
"pascalcase@npm:^0.1.1":
version: 0.1.1
resolution: "pascalcase@npm:0.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpascalcase%2Fdownload%2Fpascalcase-0.1.1.tgz"
@@ -8672,15 +8986,15 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"postcss-modules-local-by-default@npm:^3.0.2":
- version: 3.0.2
- resolution: "postcss-modules-local-by-default@npm:3.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-modules-local-by-default%2Fdownload%2Fpostcss-modules-local-by-default-3.0.2.tgz"
+"postcss-modules-local-by-default@npm:^3.0.3":
+ version: 3.0.3
+ resolution: "postcss-modules-local-by-default@npm:3.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-modules-local-by-default%2Fdownload%2Fpostcss-modules-local-by-default-3.0.3.tgz"
dependencies:
icss-utils: ^4.1.1
- postcss: ^7.0.16
+ postcss: ^7.0.32
postcss-selector-parser: ^6.0.2
- postcss-value-parser: ^4.0.0
- checksum: 32d04c364fc34681e9cba9d2b4a547b836d56d93945ba18236b3d8426840750d375c017de36a5ad26eecb9d96ab13038fe137c33844d7153cde26dad6068b3fc
+ postcss-value-parser: ^4.1.0
+ checksum: 6d34b3b1dc38cba7a3c50ef1bf6f5a0573c638b92a74cf47a730b9e029ad0f1464a944470a4aa51fdaaa8e4c47fcbb52f167d2da0342778776cdd6bafe9b146e
languageName: node
linkType: hard
@@ -8847,7 +9161,7 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"postcss-value-parser@npm:^4.0.0, postcss-value-parser@npm:^4.1.0":
+"postcss-value-parser@npm:^4.1.0":
version: 4.1.0
resolution: "postcss-value-parser@npm:4.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-value-parser%2Fdownload%2Fpostcss-value-parser-4.1.0.tgz"
checksum: 70831403886859289f650550a38889857022c5bbe264fd5d39cfad5207b3e1d33422edc031c1a922f3ae29d0dff98837a8bf126c840374d2b0079e7d57cf7d71
@@ -8865,7 +9179,7 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"postcss@npm:^7.0.0, postcss@npm:^7.0.14, postcss@npm:^7.0.16, postcss@npm:^7.0.17, postcss@npm:^7.0.2, postcss@npm:^7.0.32, postcss@npm:^7.0.5, postcss@npm:^7.0.6":
+"postcss@npm:^7.0.0, postcss@npm:^7.0.14, postcss@npm:^7.0.17, postcss@npm:^7.0.2, postcss@npm:^7.0.32, postcss@npm:^7.0.5, postcss@npm:^7.0.6":
version: 7.0.32
resolution: "postcss@npm:7.0.32::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss%2Fdownload%2Fpostcss-7.0.32.tgz"
dependencies:
@@ -8899,12 +9213,12 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"prettier@npm:^2.0.5":
- version: 2.0.5
- resolution: "prettier@npm:2.0.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-2.0.5.tgz"
+"prettier@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "prettier@npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-2.1.0.tgz"
bin:
prettier: bin-prettier.js
- checksum: d249d89361870a29b20e8b268cb09e908490b8c9e21f70393d12a213701f29ba7e95b7f9ce0ad63929c16ce475176742481911737ae3da4a498873e4a3b90990
+ checksum: f955d380d2892284c28bbfe32b1601cfcd7a24d8b310832937773b9e733f624e38ff70cbafee80e9553bdb3c55783d019163667bf9a69df4e6f7c2acdcf54c06
languageName: node
linkType: hard
@@ -8915,7 +9229,7 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"pretty-error@npm:^2.0.2":
+"pretty-error@npm:^2.1.1":
version: 2.1.1
resolution: "pretty-error@npm:2.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpretty-error%2Fdownload%2Fpretty-error-2.1.1.tgz"
dependencies:
@@ -9225,16 +9539,16 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"react-i18next@npm:^11.5.0":
- version: 11.7.0
- resolution: "react-i18next@npm:11.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-i18next%2Fdownload%2Freact-i18next-11.7.0.tgz"
+"react-i18next@npm:^11.7.1":
+ version: 11.7.1
+ resolution: "react-i18next@npm:11.7.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-i18next%2Fdownload%2Freact-i18next-11.7.1.tgz"
dependencies:
"@babel/runtime": ^7.3.1
html-parse-stringify2: 2.0.1
peerDependencies:
i18next: ">= 19.0.0"
react: ">= 16.8.0"
- checksum: 3559428ecf9753062814560b38926c2262642e7d99b9fadb0800173eca48264fb1f787970277aa0410bce7a1258d2e021ea78da373cc30e128792b25b9e0767e
+ checksum: fc62ae35c36cc332a6f2cc3bf52a4d41ec7cdfe77614b998f37707a28c72a2d3410754460543475da50c3d0ee17fa0b4f8395fa72dc3af3c0274aabc808e5f9c
languageName: node
linkType: hard
@@ -9358,7 +9672,7 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"reactstrap@npm:^8.4.1":
+"reactstrap@npm:^8.5.1":
version: 8.5.1
resolution: "reactstrap@npm:8.5.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freactstrap%2Fdownload%2Freactstrap-8.5.1.tgz"
dependencies:
@@ -9443,13 +9757,20 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"regenerator-runtime@npm:^0.13.4, regenerator-runtime@npm:^0.13.5":
+"regenerator-runtime@npm:^0.13.4":
version: 0.13.5
resolution: "regenerator-runtime@npm:0.13.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.13.5.tgz"
checksum: 8d8ee0eca26e0491085033caf2b1b95379c4db21e38d79cde52bbd4014a3865eee26ec0f4f958682e8600f185f2f5dbcd8c6685b9b9261639767929c19b5bcd2
languageName: node
linkType: hard
+"regenerator-runtime@npm:^0.13.7":
+ version: 0.13.7
+ resolution: "regenerator-runtime@npm:0.13.7::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.13.7.tgz"
+ checksum: 6ef567c662088b1b292214920cbd72443059298d477f72e1a37e0a113bafbfac9057cbfe35ae617284effc4b423493326a78561bbff7b04162c7949bdb9624e8
+ languageName: node
+ linkType: hard
+
"regenerator-transform@npm:^0.14.2":
version: 0.14.5
resolution: "regenerator-transform@npm:0.14.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-transform%2Fdownload%2Fregenerator-transform-0.14.5.tgz"
@@ -9518,7 +9839,7 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"relateurl@npm:0.2.x":
+"relateurl@npm:^0.2.7":
version: 0.2.7
resolution: "relateurl@npm:0.2.7::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Frelateurl%2Fdownload%2Frelateurl-0.2.7.tgz"
checksum: 856db0385d82022042584c14702ce58cb4d74c6b6a6d98ba85357638e64c081e6cb85adbbadebc82eec87b6e70ba43ae02d8655e565dbd4baffdc405a1b0b614
@@ -9819,12 +10140,12 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"rxjs@npm:^6.5.5":
- version: 6.6.0
- resolution: "rxjs@npm:6.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Frxjs%2Fdownload%2Frxjs-6.6.0.tgz"
+"rxjs@npm:^6.6.2":
+ version: 6.6.2
+ resolution: "rxjs@npm:6.6.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Frxjs%2Fdownload%2Frxjs-6.6.2.tgz"
dependencies:
tslib: ^1.9.0
- checksum: 32d733487caf42cc87bb0f93da5be400f2817f94a9f8af9580ab36f480aa553f584e0cfb4625b8321e8f9490094a510f9eb5e951a1d6219281d1eac1525d007b
+ checksum: 9b16cd36093b87ce454726f14783e204b80431e6657d36191877e4d9d4b0713c73e5ee8b45be336b081d47b10cd016b3812ea3bd4b27bf87942b1410aa18ee04
languageName: node
linkType: hard
@@ -9858,13 +10179,13 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"sass-loader@npm:^9.0.2":
- version: 9.0.2
- resolution: "sass-loader@npm:9.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsass-loader%2Fdownload%2Fsass-loader-9.0.2.tgz"
+"sass-loader@npm:^9.0.3":
+ version: 9.0.3
+ resolution: "sass-loader@npm:9.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsass-loader%2Fdownload%2Fsass-loader-9.0.3.tgz"
dependencies:
- klona: ^1.1.1
+ klona: ^1.1.2
loader-utils: ^2.0.0
- neo-async: ^2.6.1
+ neo-async: ^2.6.2
schema-utils: ^2.7.0
semver: ^7.3.2
peerDependencies:
@@ -9879,11 +10200,11 @@ fsevents@~2.1.2: optional: true
sass:
optional: true
- checksum: 4a27190349c3e0cd61995d45c3fbc3356a50dea5c58829e5c1d04eb66036a22350918821e73cd8f12c3a26680397a915e5af68128bcfdef566ca7c85c32355ee
+ checksum: 5ce94bb6708507c3ca6af5cada1c3442d06242aa16df38fcea059aafad0c49ad0ae980fece7c3844cc82cc2e373d7b3192c55046bf506337811b759ccdb23a4f
languageName: node
linkType: hard
-"sass@npm:^1.26.8":
+"sass@npm:^1.26.10":
version: 1.26.10
resolution: "sass@npm:1.26.10::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsass%2Fdownload%2Fsass-1.26.10.tgz"
dependencies:
@@ -10766,7 +11087,7 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"terser@npm:^4.1.2, terser@npm:^4.6.2":
+"terser@npm:^4.1.2, terser@npm:^4.6.2, terser@npm:^4.6.3":
version: 4.8.0
resolution: "terser@npm:4.8.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser%2Fdownload%2Fterser-4.8.0.tgz"
dependencies:
@@ -10807,81 +11128,81 @@ fsevents@~2.1.2: version: 0.0.0-use.local
resolution: "timeline@workspace:."
dependencies:
- "@babel/core": ^7.10.5
- "@babel/plugin-proposal-class-properties": ^7.10.1
+ "@babel/core": ^7.11.4
+ "@babel/plugin-proposal-class-properties": ^7.10.4
"@babel/plugin-proposal-decorators": ^7.10.5
- "@babel/plugin-proposal-nullish-coalescing-operator": ^7.10.1
- "@babel/plugin-proposal-optional-chaining": ^7.10.1
+ "@babel/plugin-proposal-nullish-coalescing-operator": ^7.10.4
+ "@babel/plugin-proposal-optional-chaining": ^7.11.0
"@babel/plugin-syntax-dynamic-import": ^7.8.3
- "@babel/preset-env": ^7.10.2
- "@babel/preset-react": ^7.10.1
- "@babel/preset-typescript": ^7.10.1
+ "@babel/preset-env": ^7.11.0
+ "@babel/preset-react": ^7.10.4
+ "@babel/preset-typescript": ^7.10.4
"@hot-loader/react-dom": ^16.13.0
"@types/classnames": ^2.2.10
"@types/crypto-js": ^3.1.47
- "@types/lodash": ^4.14.155
- "@types/node": ^14.0.11
- "@types/react": ^16.9.35
+ "@types/lodash": ^4.14.159
+ "@types/node": ^14.6.0
+ "@types/react": ^16.9.46
"@types/react-dom": ^16.9.8
"@types/react-responsive": ^8.0.2
- "@types/react-router": ^5.1.7
+ "@types/react-router": ^5.1.8
"@types/react-router-dom": ^5.1.5
- "@types/reactstrap": ^8.4.2
+ "@types/reactstrap": ^8.5.1
"@types/webpack-env": ^1.15.2
"@types/xregexp": ^4.3.0
- "@typescript-eslint/eslint-plugin": ^3.6.1
- "@typescript-eslint/parser": ^3.6.1
+ "@typescript-eslint/eslint-plugin": ^3.9.1
+ "@typescript-eslint/parser": ^3.9.1
"@yarnpkg/pnpify": ^2.1.0
- axios: ^0.19.2
+ axios: ^0.20.0
babel-loader: ^8.1.0
babel-plugin-transform-builtin-extend: ^1.1.2
- bootstrap: ^4.5.0
- bootstrap-icons: ^1.0.0-alpha4
+ bootstrap: ^4.5.2
+ bootstrap-icons: ^1.0.0-alpha5
classnames: ^2.2.6
clean-webpack-plugin: ^3.0.0
clsx: ^1.1.1
- copy-webpack-plugin: ^6.0.2
+ copy-webpack-plugin: ^6.0.3
core-js: ^3.6.5
crypto-js: ^4.0.0
- css-loader: ^3.5.3
- eslint: ^7.2.0
+ css-loader: ^4.2.1
+ eslint: ^7.7.0
eslint-config-prettier: ^6.11.0
- eslint-plugin-prettier: ^3.1.3
- eslint-plugin-react: ^7.20.0
- eslint-plugin-react-hooks: ^4.0.8
+ eslint-plugin-prettier: ^3.1.4
+ eslint-plugin-react: ^7.20.6
+ eslint-plugin-react-hooks: ^4.1.0
file-loader: ^6.0.0
- html-webpack-plugin: ^3.2.0
+ html-webpack-plugin: ^4.3.0
http-server: ^0.12.3
- i18next: ^19.6.2
- i18next-browser-languagedetector: ^5.0.0
- localforage: ^1.7.4
- lodash: ^4.17.15
+ i18next: ^19.7.0
+ i18next-browser-languagedetector: ^6.0.1
+ localforage: ^1.9.0
+ lodash: ^4.17.20
mini-css-extract-plugin: ^0.10.0
pepjs: ^0.5.2
pnp-webpack-plugin: ^1.6.4
postcss-loader: ^3.0.0
postcss-preset-env: ^6.7.0
- prettier: ^2.0.5
+ prettier: ^2.1.0
react: ^16.13.1
react-dom: ^16.13.1
react-hot-loader: ^4.12.21
- react-i18next: ^11.5.0
+ react-i18next: ^11.7.1
react-inlinesvg: ^2.0.0
react-responsive: ^8.1.0
react-router: ^5.2.0
react-router-dom: ^5.2.0
- reactstrap: ^8.4.1
- regenerator-runtime: ^0.13.5
- rxjs: ^6.5.5
- sass: ^1.26.8
- sass-loader: ^9.0.2
+ reactstrap: ^8.5.1
+ regenerator-runtime: ^0.13.7
+ rxjs: ^6.6.2
+ sass: ^1.26.10
+ sass-loader: ^9.0.3
style-loader: ^1.2.1
- ts-loader: ^8.0.1
- typescript: ^3.9.7
+ ts-loader: ^8.0.3
+ typescript: ^4.0.2
url-loader: ^4.1.0
- webpack: ^4.43.0
+ webpack: ^4.44.1
webpack-chain: ^6.5.1
- webpack-cli: ^3.3.11
+ webpack-cli: ^3.3.12
webpack-dev-server: ^3.11.0
workbox-precaching: ^5.1.3
workbox-routing: ^5.1.3
@@ -10983,13 +11304,6 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"toposort@npm:^1.0.0":
- version: 1.0.7
- resolution: "toposort@npm:1.0.7::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftoposort%2Fdownload%2Ftoposort-1.0.7.tgz"
- checksum: 32544ffadbbcdb08784193a85c5540751884a666862cc5dc23040ebce078d110ced9b9d351b1b159deaa0d162c43f0b534e3b57449a3b8e878d07ad0dfdbea37
- languageName: node
- linkType: hard
-
"tough-cookie@npm:~2.5.0":
version: 2.5.0
resolution: "tough-cookie@npm:2.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftough-cookie%2Fdownload%2Ftough-cookie-2.5.0.tgz"
@@ -11000,9 +11314,9 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"ts-loader@npm:^8.0.1":
- version: 8.0.1
- resolution: "ts-loader@npm:8.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fts-loader%2Fdownload%2Fts-loader-8.0.1.tgz"
+"ts-loader@npm:^8.0.3":
+ version: 8.0.3
+ resolution: "ts-loader@npm:8.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fts-loader%2Fdownload%2Fts-loader-8.0.3.tgz"
dependencies:
chalk: ^2.3.0
enhanced-resolve: ^4.0.0
@@ -11011,7 +11325,7 @@ fsevents@~2.1.2: semver: ^6.0.0
peerDependencies:
typescript: "*"
- checksum: 62772faf481c687f2ddf16cb6c7e8ec1a989868bfc442baec6a28b78a5bcc5476bf1c10d22311f2bed4ef4cf47f2a00fba21e9702b8b2f3ae1fd9715c93d78cb
+ checksum: fe39e52d6f571889481e80586bf20006c15bc60670ec5f8c8d294e4b1a95c5d99bb6675ab5012aa1f2edbde7963fc8018a3fefded0b82e4fc23a3f1205e42671
languageName: node
linkType: hard
@@ -11027,7 +11341,7 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-"tslib@npm:^1.13.0, tslib@npm:^1.8.1, tslib@npm:^1.9.0":
+"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"
checksum: 5dc3bdaea3b67c76ef4a14c28fcb2171da7bcf292fd9c59a260098729626b1ce766c52b588f08e324ed9a0c52ea8a93a815920f980d75981abc9d850fbf310fb
@@ -11122,35 +11436,23 @@ fsevents@~2.1.2: languageName: node
linkType: hard
-typescript@^3.9.7:
- version: 3.9.7
- resolution: "typescript@npm:3.9.7::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftypescript%2Fdownload%2Ftypescript-3.9.7.tgz"
+typescript@^4.0.2:
+ version: 4.0.2
+ resolution: "typescript@npm:4.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftypescript%2Fdownload%2Ftypescript-4.0.2.tgz"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
- checksum: 10848a9c35fd8c70a8792b8bd9485317534bcd58768793d3b7d9c7486e9fd30cf345f83fa2a324e0bf6088bc8a4d8d061d58fda38b18c2ff187cf01fbbff6267
+ checksum: cc0e7806eee7997a1b4b2990badacc4a8d089893ed0a377f35c9658e2ac392503cb340d0187203ed82e36e427dda94b0fb7107e44a71cca99efac86be26e16ee
languageName: node
linkType: hard
-"typescript@patch:typescript@^3.9.7#builtin<compat/typescript>":
- version: 3.9.7
- resolution: "typescript@patch:typescript@npm%3A3.9.7%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-3.9.7.tgz#builtin<compat/typescript>::version=3.9.7&hash=5b02a2"
+"typescript@patch:typescript@^4.0.2#builtin<compat/typescript>":
+ version: 4.0.2
+ resolution: "typescript@patch:typescript@npm%3A4.0.2%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Ftypescript%252Fdownload%252Ftypescript-4.0.2.tgz#builtin<compat/typescript>::version=4.0.2&hash=5b02a2"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
- checksum: f0d3d9c987860c7c458229ab6dd7e3d322405db36b70abccba610b5efd9f9451e4e67a3fc7983c0d3741033c1f1a8d7aa859a1510caa8f20fad762fc39648bfa
- languageName: node
- linkType: hard
-
-"uglify-js@npm:3.4.x":
- version: 3.4.10
- resolution: "uglify-js@npm:3.4.10::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fuglify-js%2Fdownload%2Fuglify-js-3.4.10.tgz"
- dependencies:
- commander: ~2.19.0
- source-map: ~0.6.1
- bin:
- uglifyjs: bin/uglifyjs
- checksum: 432811d1001fa8e0a9ca4e1867300f4b95abbe80b3025185220c3982448dd2bbb0d2ec2a192002ebc88a8ba3e43d3289ff90bc6a2d2ddf02a92f218ba6bd703b
+ checksum: b8b689ef994cce4fe59950d56ddfffce3c4bdda8edb85b72e752d4a6d27bf7df8a318e76ccde25cbe6e642058f2f4ccf47187db4b243bbc98278a2844db9461b
languageName: node
linkType: hard
@@ -11278,13 +11580,6 @@ typescript@^3.9.7: languageName: node
linkType: hard
-"upper-case@npm:^1.1.1":
- version: 1.1.3
- resolution: "upper-case@npm:1.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fupper-case%2Fdownload%2Fupper-case-1.1.3.tgz"
- checksum: 82bfe8d6e11981608c68629de8221daf7c7e091aef9243bd7595a306beaeb9ff145afeaf003f5f1fbe1acb20de30e52421cc4564b7617375da52838da9173d19
- languageName: node
- linkType: hard
-
"uri-js@npm:^4.2.2":
version: 4.2.2
resolution: "uri-js@npm:4.2.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Furi-js%2Fdownload%2Furi-js-4.2.2.tgz"
@@ -11474,11 +11769,11 @@ typescript@^3.9.7: languageName: node
linkType: hard
-"watchpack@npm:^1.6.1":
- version: 1.7.2
- resolution: "watchpack@npm:1.7.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwatchpack%2Fdownload%2Fwatchpack-1.7.2.tgz"
+"watchpack@npm:^1.7.4":
+ version: 1.7.4
+ resolution: "watchpack@npm:1.7.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwatchpack%2Fdownload%2Fwatchpack-1.7.4.tgz"
dependencies:
- chokidar: ^3.4.0
+ chokidar: ^3.4.1
graceful-fs: ^4.1.2
neo-async: ^2.5.0
watchpack-chokidar2: ^2.0.0
@@ -11487,7 +11782,7 @@ typescript@^3.9.7: optional: true
watchpack-chokidar2:
optional: true
- checksum: a9d630dd29279b91bb1b1dd319e9142f13906e8cc973c860e0662828cff84e2a3235a66da62759cb4f12dc76a6f672760e62b2c8a6406ff80d5e4977b5717e83
+ checksum: 61876d6e60ddb1e9b0a6143c65a4453543bb1a27638254635d179d4681f15af200de9a61c1a3faec220a29e41ca37381e604345ffa9d48c064a29cff4cb25732
languageName: node
linkType: hard
@@ -11510,7 +11805,7 @@ typescript@^3.9.7: languageName: node
linkType: hard
-"webpack-cli@npm:^3.3.11":
+"webpack-cli@npm:^3.3.12":
version: 3.3.12
resolution: "webpack-cli@npm:3.3.12::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-cli%2Fdownload%2Fwebpack-cli-3.3.12.tgz"
dependencies:
@@ -11617,9 +11912,9 @@ typescript@^3.9.7: languageName: node
linkType: hard
-"webpack@npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz, webpack@npm:^4.43.0":
- version: 4.43.0
- resolution: "webpack@npm:4.43.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.43.0.tgz"
+"webpack@npm:^4.44.1":
+ version: 4.44.1
+ resolution: "webpack@npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"
dependencies:
"@webassemblyjs/ast": 1.9.0
"@webassemblyjs/helper-module-context": 1.9.0
@@ -11629,7 +11924,7 @@ typescript@^3.9.7: ajv: ^6.10.2
ajv-keywords: ^3.4.1
chrome-trace-event: ^1.0.2
- enhanced-resolve: ^4.1.0
+ enhanced-resolve: ^4.3.0
eslint-scope: ^4.0.3
json-parse-better-errors: ^1.0.2
loader-runner: ^2.4.0
@@ -11642,11 +11937,19 @@ typescript@^3.9.7: schema-utils: ^1.0.0
tapable: ^1.1.3
terser-webpack-plugin: ^1.4.3
- watchpack: ^1.6.1
+ watchpack: ^1.7.4
webpack-sources: ^1.4.1
+ peerDependencies:
+ webpack-cli: "*"
+ webpack-command: "*"
+ peerDependenciesMeta:
+ webpack-cli:
+ optional: true
+ webpack-command:
+ optional: true
bin:
webpack: bin/webpack.js
- checksum: 9f1e6375ba28368b4a0d02a0807aa4e148b101244d7ab698c99ac478e3043cdacf7d7c89aa7d4af9549509be7d23878ef863bd6a9540e89a18dd2c04e82e2b4f
+ checksum: d4d140010bdf1fe4a5ef5435733e4b4fb71081cafd5e995adca0ca6259e271c7b51af909477e03bbbeb35487bd399a672bb0bc4a4726baebac059444b489b412
languageName: node
linkType: hard
|