diff --git a/web/cashtab/.gitignore b/web/cashtab/.gitignore --- a/web/cashtab/.gitignore +++ b/web/cashtab/.gitignore @@ -28,8 +28,5 @@ *.pem dist/ -# Ignore fbt generated files -.source_strings.json -.src_manifest.json -.enum_manifest.json -src/translatedFbts.json +# Ignore react-intl generated files +src/compiled-lang diff --git a/web/cashtab/config/paths.js b/web/cashtab/config/paths.js --- a/web/cashtab/config/paths.js +++ b/web/cashtab/config/paths.js @@ -70,8 +70,6 @@ appBuild: resolveApp('build'), appPublic: resolveApp('public'), appHtml: resolveApp('public/index.html'), - appI18nJs: resolveApp('src/i18n/init.js'), - appI18n: resolveApp('src/i18n'), appIndexJs: resolveModule(resolveApp, 'src/index'), appPackageJson: resolveApp('package.json'), appSrc: resolveApp('src'), diff --git a/web/cashtab/config/webpack.config.js b/web/cashtab/config/webpack.config.js --- a/web/cashtab/config/webpack.config.js +++ b/web/cashtab/config/webpack.config.js @@ -274,7 +274,6 @@ isEnvDevelopment && require.resolve('react-dev-utils/webpackHotDevClient'), // Finally, this is your app's code: - paths.appI18nJs, paths.appIndexJs, // We include the app code last so that if there is a runtime error during // initialization, it doesn't blow up the WebpackDevServer client, and @@ -395,11 +394,9 @@ // We placed these paths second because we want `node_modules` to "win" // if there are any conflicts. This matches Node resolution mechanism. // https://github.com/facebook/create-react-app/issues/253 - modules: [ - 'node_modules', - paths.appI18n, - paths.appNodeModules, - ].concat(modules.additionalModulePaths || []), + modules: ['node_modules', paths.appNodeModules].concat( + modules.additionalModulePaths || [], + ), // These are the reasonable defaults supported by the Node ecosystem. // We also include JSX as a common component filename extension to support // some tools, although we do not recommend using it, see: @@ -484,16 +481,15 @@ }, ], [ - 'babel-plugin-fbt', + require.resolve( + 'babel-plugin-formatjs', + ), { - fbtEnumPath: path.join( - paths.appPath, - '.enum_manifest.json', - ), - extraOptions: { __self: true }, + idInterpolationPattern: + '[sha512:contenthash:base64:6]', + ast: true, }, ], - 'babel-plugin-fbt-runtime', ], // This is a feature of `babel-loader` for webpack (not Babel itself). // It enables caching results in ./node_modules/.cache/babel-loader/ diff --git a/web/cashtab/extension/src/components/App.js b/web/cashtab/extension/src/components/App.js --- a/web/cashtab/extension/src/components/App.js +++ b/web/cashtab/extension/src/components/App.js @@ -28,7 +28,7 @@ useHistory, } from 'react-router-dom'; -import fbt from 'fbt'; +import { FormattedMessage } from 'react-intl'; const GlobalStyle = createGlobalStyle` .ant-modal-wrap > div > div.ant-modal-content > div > div > div.ant-modal-confirm-btns > button, .ant-modal > button, .ant-modal-confirm-btns > button, .ant-modal-footer > button { @@ -254,7 +254,10 @@ onClick={() => history.push('/wallet')} > - Wallet + history.push('/send')} > - Send + history.push('/configure')} > - Settings + ) : null} diff --git a/web/cashtab/lang/en-us.json b/web/cashtab/lang/en-us.json new file mode 100644 --- /dev/null +++ b/web/cashtab/lang/en-us.json @@ -0,0 +1,14 @@ +{ + "BndWcC": { + "developer_comment": "Settings menu button", + "string": "Settings" + }, + "etTXTv": { + "developer_comment": "Send menu button", + "string": "Send" + }, + "w/8GKE": { + "developer_comment": "Wallet menu button", + "string": "Wallet" + } +} diff --git a/web/cashtab/lang/pt-br.json b/web/cashtab/lang/pt-br.json new file mode 100644 --- /dev/null +++ b/web/cashtab/lang/pt-br.json @@ -0,0 +1,14 @@ +{ + "BndWcC": { + "developer_comment": "Settings menu button", + "string": "Opções" + }, + "etTXTv": { + "developer_comment": "Send menu button", + "string": "Enviar" + }, + "w/8GKE": { + "developer_comment": "Wallet menu button", + "string": "Carteira" + } +} diff --git a/web/cashtab/package-lock.json b/web/cashtab/package-lock.json --- a/web/cashtab/package-lock.json +++ b/web/cashtab/package-lock.json @@ -31,6 +31,7 @@ "react-dom": "^17.0.1", "react-ga": "^3.3.0", "react-image": "^4.0.3", + "react-intl": "^5.20.4", "react-router": "^5.2.0", "react-router-dom": "^5.2.0", "styled-components": "^4.4.0" @@ -39,6 +40,7 @@ "@ant-design/dark-theme": "^1.0.3", "@babel/core": "^7.6.0", "@babel/node": "^7.12.6", + "@formatjs/cli": "^4.2.27", "@psf/bch-js": "^4.16.1", "@svgr/webpack": "^5.5.0", "@testing-library/react": "^11.2.2", @@ -48,6 +50,7 @@ "babel-loader": "^8.0.6", "babel-plugin-fbt": "^0.19.1", "babel-plugin-fbt-runtime": "^0.9.16", + "babel-plugin-formatjs": "^10.3.2", "babel-plugin-named-asset-import": "^0.3.7", "babel-preset-react-app": "^10.0.0", "camelcase": "^5.3.1", @@ -1635,6 +1638,240 @@ "@babel/plugin-syntax-optional-chaining": "^7.0.0" } }, + "node_modules/@formatjs/cli": { + "version": "4.2.27", + "resolved": "https://registry.npmjs.org/@formatjs/cli/-/cli-4.2.27.tgz", + "integrity": "sha512-P+y3nIBa+IMfv8dKPdZ38xhF/l9AghsU8kKi2onUJLpvjjDdjTEUTleaPpVghZKhe6BqNbso+anludxlZUdKoA==", + "dev": true, + "dependencies": { + "@formatjs/icu-messageformat-parser": "2.0.7", + "@formatjs/ts-transformer": "3.4.5", + "@types/json-stable-stringify": "^1.0.32", + "@types/lodash": "^4.14.150", + "@types/node": "14", + "@vue/compiler-core": "^3.0.0", + "@vue/compiler-sfc": "^3.0.5", + "chalk": "^4.0.0", + "commander": "8", + "fast-glob": "^3.2.4", + "fs-extra": "^9.0.0", + "json-stable-stringify": "^1.0.1", + "lodash": "^4.17.15", + "loud-rejection": "^2.2.0", + "tslib": "^2.1.0", + "typescript": "^4.0" + }, + "bin": { + "formatjs": "bin/formatjs" + } + }, + "node_modules/@formatjs/cli/node_modules/@formatjs/ts-transformer": { + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/@formatjs/ts-transformer/-/ts-transformer-3.4.5.tgz", + "integrity": "sha512-VzjT9jbpizZhwvtX/jaoTOeHQ/nvEx9ttzDrRXcFIGXyxupBZKTxr/+v6j3NjUmeiuN3JfaXhZUYmG+zsS0kxw==", + "dev": true, + "dependencies": { + "@formatjs/icu-messageformat-parser": "2.0.7", + "chalk": "^4.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "ts-jest": "27", + "typescript": "4" + }, + "peerDependenciesMeta": { + "ts-jest": { + "optional": true + } + } + }, + "node_modules/@formatjs/cli/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@formatjs/cli/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@formatjs/cli/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@formatjs/cli/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@formatjs/cli/node_modules/commander": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.0.0.tgz", + "integrity": "sha512-Xvf85aAtu6v22+E5hfVoLHqyul/jyxh91zvqk/ioJTQuJR7Z78n7H558vMPKanPSRgIEeZemT92I2g9Y8LPbSQ==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@formatjs/cli/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@formatjs/cli/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@formatjs/cli/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@formatjs/cli/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@formatjs/cli/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@formatjs/ecma402-abstract": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.9.4.tgz", + "integrity": "sha512-ePJXI7tWC9PBxQxS7jtbkCLGVmpC8MH8n9Yjmg8dsh9wXK9svu7nAbq76Oiu5Zb+5GVkLkeTVerlSvHCbNImlA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@formatjs/fast-memoize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-1.1.1.tgz", + "integrity": "sha512-mIqBr5uigIlx13eZTOPSEh2buDiy3BCdMYUtewICREQjbb4xarDiVWoXSnrERM7NanZ+0TAHNXSqDe6HpEFQUg==" + }, + "node_modules/@formatjs/icu-messageformat-parser": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.0.7.tgz", + "integrity": "sha512-gduYfh/YdBTmb1XzLueNaofiGZVMrkaDg0RSa0GNztKWs4QXIRS+28cjcuWNpV0q5S8aiLMkP7SHQpZKnPCHLw==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.9.4", + "@formatjs/icu-skeleton-parser": "1.2.8", + "tslib": "^2.1.0" + } + }, + "node_modules/@formatjs/icu-skeleton-parser": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.2.8.tgz", + "integrity": "sha512-KLSSAA7Q2Uv7msij8saaOE5rpsHK/2WkfS3737JnDyVTFOYe8l2OarIBUoTC5gi1BnCgiN/1icZlqXwyUX6obA==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.9.4", + "tslib": "^2.1.0" + } + }, + "node_modules/@formatjs/intl": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-1.13.2.tgz", + "integrity": "sha512-aonTXXaI/Guqr4t87m/XWfmgE9aPefDTLRnCwadxBDkUHw1/HQeUV+lp/3BgiPZfemIdBq9UgdigDCwrpEwrTA==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.9.4", + "@formatjs/fast-memoize": "1.1.1", + "@formatjs/icu-messageformat-parser": "2.0.7", + "@formatjs/intl-displaynames": "5.1.6", + "@formatjs/intl-listformat": "6.2.6", + "intl-messageformat": "9.7.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "typescript": "^4.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@formatjs/intl-displaynames": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/@formatjs/intl-displaynames/-/intl-displaynames-5.1.6.tgz", + "integrity": "sha512-s0eDyQFM2gQIPgn+MyaH+UcCvp6ui2ft9UW1gsIkjBkaprRlzKMd3fjxcUFO/I7oyXXA6FYR4qHR8u1I0+PvXA==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.9.4", + "tslib": "^2.1.0" + } + }, + "node_modules/@formatjs/intl-listformat": { + "version": "6.2.6", + "resolved": "https://registry.npmjs.org/@formatjs/intl-listformat/-/intl-listformat-6.2.6.tgz", + "integrity": "sha512-6FMdQY1+QKqJW5IhsVPFuEaR/uRiBKP+Y1oDvamZKzDfJ2vQmk9jqSF51VztlZH8XSfdO0IgvBzeRPHahKChQA==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.9.4", + "tslib": "^2.1.0" + } + }, "node_modules/@fortawesome/fontawesome-free": { "version": "5.15.3", "hasInstallScript": true, @@ -2826,6 +3063,15 @@ "@babel/types": "^7.0.0" } }, + "node_modules/@types/babel__helper-plugin-utils": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@types/babel__helper-plugin-utils/-/babel__helper-plugin-utils-7.10.0.tgz", + "integrity": "sha512-60YtHzhQ9HAkToHVV+TB4VLzBn9lrfgrsOjiJMtbv/c1jPdekBxaByd6DMsGBzROXWoIL6U3lEFvvbu69RkUoA==", + "dev": true, + "dependencies": { + "@types/babel__core": "*" + } + }, "node_modules/@types/babel__template": { "version": "7.4.0", "dev": true, @@ -2853,9 +3099,10 @@ } }, "node_modules/@types/estree": { - "version": "0.0.47", - "dev": true, - "license": "MIT" + "version": "0.0.48", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.48.tgz", + "integrity": "sha512-LfZwXoGUDo0C3me81HXgkBg5CTQYb6xzEl+fNmbO4JdRiSKQ8A0GD1OBBvKAIsbCUgoyAty7m99GqqMQe784ew==", + "dev": true }, "node_modules/@types/glob": { "version": "7.1.3", @@ -2874,6 +3121,15 @@ "@types/node": "*" } }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/html-minifier-terser": { "version": "5.1.1", "dev": true, @@ -2905,10 +3161,22 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/json-stable-stringify": { + "version": "1.0.33", + "resolved": "https://registry.npmjs.org/@types/json-stable-stringify/-/json-stable-stringify-1.0.33.tgz", + "integrity": "sha512-qEWiQff6q2tA5gcJGWwzplQcXdJtm+0oy6IHGHzlOf3eFAkGE/FIPXZK9ofWgNSHVp8AFFI33PJJshS0ei3Gvw==", + "dev": true + }, "node_modules/@types/json5": { "version": "0.0.29", "license": "MIT" }, + "node_modules/@types/lodash": { + "version": "4.14.171", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.171.tgz", + "integrity": "sha512-7eQ2xYLLI/LsicL2nejW9Wyko3lcpN6O/z0ZLHrEQsg280zIdCv1t/0m6UtBjUHokCGBQ3gYTbHzDkZ1xOBwwg==", + "dev": true + }, "node_modules/@types/minimatch": { "version": "3.0.3", "dev": true, @@ -2936,7 +3204,6 @@ }, "node_modules/@types/prop-types": { "version": "15.7.3", - "dev": true, "license": "MIT" }, "node_modules/@types/q": { @@ -2946,7 +3213,6 @@ }, "node_modules/@types/react": { "version": "17.0.3", - "dev": true, "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -2964,7 +3230,6 @@ }, "node_modules/@types/scheduler": { "version": "0.16.1", - "dev": true, "license": "MIT" }, "node_modules/@types/source-list-map": { @@ -3292,6 +3557,146 @@ "lodash.throttle": "^4.1.1" } }, + "node_modules/@vue/compiler-core": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.1.4.tgz", + "integrity": "sha512-TnUz+1z0y74O/A4YKAbzsdUfamyHV73MihrEfvettWpm9bQKVoZd1nEmR1cGN9LsXWlwAvVQBetBlWdOjmQO5Q==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.12.0", + "@babel/types": "^7.12.0", + "@vue/shared": "3.1.4", + "estree-walker": "^2.0.1", + "source-map": "^0.6.1" + } + }, + "node_modules/@vue/compiler-core/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.1.4.tgz", + "integrity": "sha512-3tG2ScHkghhUBuFwl9KgyZhrS8CPFZsO7hUDekJgIp5b1OMkROr4AvxHu6rRMl4WkyvYkvidFNBS2VfOnwa6Kw==", + "dev": true, + "dependencies": { + "@vue/compiler-core": "3.1.4", + "@vue/shared": "3.1.4" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.1.4.tgz", + "integrity": "sha512-4KDQg60Khy3SgnF+V/TB2NZqzmM4TyGRmzsxqG1SebGdMSecCweFDSlI/F1vDYk6dKiCHgmpoT9A1sLxswkJ0A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.13.9", + "@babel/types": "^7.13.0", + "@types/estree": "^0.0.48", + "@vue/compiler-core": "3.1.4", + "@vue/compiler-dom": "3.1.4", + "@vue/compiler-ssr": "3.1.4", + "@vue/shared": "3.1.4", + "consolidate": "^0.16.0", + "estree-walker": "^2.0.1", + "hash-sum": "^2.0.0", + "lru-cache": "^5.1.1", + "magic-string": "^0.25.7", + "merge-source-map": "^1.1.0", + "postcss": "^8.1.10", + "postcss-modules": "^4.0.0", + "postcss-selector-parser": "^6.0.4", + "source-map": "^0.6.1" + }, + "peerDependencies": { + "vue": "3.1.4" + } + }, + "node_modules/@vue/compiler-sfc/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@vue/compiler-sfc/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/compiler-sfc/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.1.4.tgz", + "integrity": "sha512-Box8fCuCFPp0FuimIswjDkjwiSDCBkHvt/xVALyFkYCiIMWv2eR53fIjmlsnEHhcBuZ+VgRC+UanCTcKvSA1gA==", + "dev": true, + "dependencies": { + "@vue/compiler-dom": "3.1.4", + "@vue/shared": "3.1.4" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.4.tgz", + "integrity": "sha512-YDlgii2Cr9yAoKVZFzgY4j0mYlVT73986X3e5SPp6ifqckSEoFSUWXZK2Tb53TB/9qO29BEEbspnKD3m3wAwkA==", + "dev": true, + "peer": true, + "dependencies": { + "@vue/shared": "3.1.4" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.1.4.tgz", + "integrity": "sha512-qmVJgJuFxfT7M4qHQ4M6KqhKC66fjuswK+aBivE8dWiZ2rtIGl9gtJGpwqwjQEcKEBTOfvvrtrwBncYArJUO8Q==", + "dev": true, + "peer": true, + "dependencies": { + "@vue/reactivity": "3.1.4", + "@vue/shared": "3.1.4" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.1.4.tgz", + "integrity": "sha512-vbmwgTxku1BU87Kw7r29adv0OIrDXCW0PslOPQT0O/9R5SqcXgS94Yj6zsztDjvghegenwIAPNLlDR1Auh5s+w==", + "dev": true, + "peer": true, + "dependencies": { + "@vue/runtime-core": "3.1.4", + "@vue/shared": "3.1.4", + "csstype": "^2.6.8" + } + }, + "node_modules/@vue/runtime-dom/node_modules/csstype": { + "version": "2.6.17", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.17.tgz", + "integrity": "sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A==", + "dev": true, + "peer": true + }, + "node_modules/@vue/shared": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.4.tgz", + "integrity": "sha512-6O45kZAmkLvzGLToBxEz4lR2W6kXohCtebV2UxjH9GXjd8X9AhEn68FN9eNanFtWNzvgw1hqd6HkPRVQalqf7Q==", + "dev": true + }, "node_modules/@webassemblyjs/ast": { "version": "1.9.0", "dev": true, @@ -3980,6 +4385,15 @@ "version": "1.0.0", "license": "MIT" }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/array-flatten": { "version": "2.1.2", "dev": true, @@ -4585,6 +4999,114 @@ "babel-plugin-fbt": "^0.19.x" } }, + "node_modules/babel-plugin-formatjs": { + "version": "10.3.2", + "resolved": "https://registry.npmjs.org/babel-plugin-formatjs/-/babel-plugin-formatjs-10.3.2.tgz", + "integrity": "sha512-u1A6/PpwGD4xb3X+egEb6BQ2QbumHFgJYduGCxMiRhONfEsVeD2SdvDlOsS1CWOr/03SFIB/U5j+QbUM1lh7sw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-jsx": "7", + "@babel/traverse": "7", + "@babel/types": "^7.9.5", + "@formatjs/icu-messageformat-parser": "2.0.7", + "@formatjs/ts-transformer": "3.4.5", + "@types/babel__core": "^7.1.7", + "@types/babel__helper-plugin-utils": "7", + "tslib": "^2.1.0" + } + }, + "node_modules/babel-plugin-formatjs/node_modules/@formatjs/ts-transformer": { + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/@formatjs/ts-transformer/-/ts-transformer-3.4.5.tgz", + "integrity": "sha512-VzjT9jbpizZhwvtX/jaoTOeHQ/nvEx9ttzDrRXcFIGXyxupBZKTxr/+v6j3NjUmeiuN3JfaXhZUYmG+zsS0kxw==", + "dev": true, + "dependencies": { + "@formatjs/icu-messageformat-parser": "2.0.7", + "chalk": "^4.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "ts-jest": "27", + "typescript": "4" + }, + "peerDependenciesMeta": { + "ts-jest": { + "optional": true + } + } + }, + "node_modules/babel-plugin-formatjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/babel-plugin-formatjs/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/babel-plugin-formatjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/babel-plugin-formatjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/babel-plugin-formatjs/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-formatjs/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/babel-plugin-istanbul": { "version": "6.0.0", "dev": true, @@ -6504,6 +7026,18 @@ "version": "1.2.0", "dev": true }, + "node_modules/consolidate": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.16.0.tgz", + "integrity": "sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ==", + "dev": true, + "dependencies": { + "bluebird": "^3.7.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, "node_modules/constants-browserify": { "version": "1.0.0", "dev": true, @@ -7464,13 +7998,24 @@ }, "node_modules/csstype": { "version": "3.0.7", - "dev": true, "license": "MIT" }, "node_modules/cuid": { "version": "2.1.8", "license": "MIT" }, + "node_modules/currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "dependencies": { + "array-find-index": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/custom-error-instance": { "version": "2.1.1", "license": "ISC" @@ -9193,6 +9738,12 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, "node_modules/esutils": { "version": "2.0.3", "license": "BSD-2-Clause", @@ -10514,6 +11065,41 @@ "version": "1.0.1", "license": "MIT" }, + "node_modules/generic-names": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generic-names/-/generic-names-2.0.1.tgz", + "integrity": "sha512-kPCHWa1m9wGG/OwQpeweTwM/PYiQLrUIxXbt/P4Nic3LbGjCP0YwrALHW1uNLKZ0LIMg+RF+XRlj2ekT9ZlZAQ==", + "dev": true, + "dependencies": { + "loader-utils": "^1.1.0" + } + }, + "node_modules/generic-names/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/generic-names/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "license": "MIT", @@ -10932,6 +11518,12 @@ "node": ">=4" } }, + "node_modules/hash-sum": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", + "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==", + "dev": true + }, "node_modules/hash.js": { "version": "1.1.7", "license": "MIT", @@ -11406,6 +11998,12 @@ "node": ">=0.10.0" } }, + "node_modules/icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", + "dev": true + }, "node_modules/icss-utils": { "version": "5.1.0", "dev": true, @@ -11706,6 +12304,16 @@ "node": ">= 0.10" } }, + "node_modules/intl-messageformat": { + "version": "9.7.1", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.7.1.tgz", + "integrity": "sha512-DNiuD+/59G9qaYu3U0KgwCV0zpN9XRoUvc8izSNCNAA5MknhiIUONFE0WtScP+E/7JfoENu+CX57P/SURRbI0A==", + "dependencies": { + "@formatjs/fast-memoize": "1.1.1", + "@formatjs/icu-messageformat-parser": "2.0.7", + "tslib": "^2.1.0" + } + }, "node_modules/invariant": { "version": "2.2.4", "license": "MIT", @@ -15684,6 +16292,12 @@ "lodash._basetostring": "~4.12.0" } }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "dev": true + }, "node_modules/lodash.debounce": { "version": "4.0.8", "dev": true, @@ -15818,6 +16432,19 @@ "loose-envify": "cli.js" } }, + "node_modules/loud-rejection": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-2.2.0.tgz", + "integrity": "sha512-S0FayMXku80toa5sZ6Ro4C+s+EtFDCsyJNG/AzFMfX3AxD5Si4dZsgzm/kKnbOxHl5Cv8jBlno8+3XYIh2pNjQ==", + "dev": true, + "dependencies": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/lower-case": { "version": "2.0.2", "dev": true, @@ -15852,6 +16479,15 @@ "lz-string": "bin/bin.js" } }, + "node_modules/magic-string": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.4" + } + }, "node_modules/make-dir": { "version": "2.1.0", "dev": true, @@ -15996,6 +16632,24 @@ "dev": true, "license": "MIT" }, + "node_modules/merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "dev": true, + "dependencies": { + "source-map": "^0.6.1" + } + }, + "node_modules/merge-source-map/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "dev": true, @@ -19898,6 +20552,25 @@ "node": ">=6" } }, + "node_modules/postcss-modules": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/postcss-modules/-/postcss-modules-4.1.3.tgz", + "integrity": "sha512-dBT39hrXe4OAVYJe/2ZuIZ9BzYhOe7t+IhedYeQ2OxKwDpAGlkEN/fR0fGnrbx4BvgbMReRX4hCubYK9cE/pJQ==", + "dev": true, + "dependencies": { + "generic-names": "^2.0.1", + "icss-replace-symbols": "^1.1.0", + "lodash.camelcase": "^4.3.0", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "string-hash": "^1.1.1" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, "node_modules/postcss-modules-extract-imports": { "version": "3.0.0", "dev": true, @@ -22450,6 +23123,31 @@ "react-dom": ">=16.8" } }, + "node_modules/react-intl": { + "version": "5.20.4", + "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-5.20.4.tgz", + "integrity": "sha512-lYUL8hWkRHbpVtedGSjpQ1kK/x2AAGZHGgOHsU0SFDufHo2aS7xdvRcaxXD3PMVDuh53KcU+vTaun+bcrwKpbA==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.9.4", + "@formatjs/icu-messageformat-parser": "2.0.7", + "@formatjs/intl": "1.13.2", + "@formatjs/intl-displaynames": "5.1.6", + "@formatjs/intl-listformat": "6.2.6", + "@types/hoist-non-react-statics": "^3.3.1", + "hoist-non-react-statics": "^3.3.2", + "intl-messageformat": "9.7.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "react": "^16.3.0 || 17", + "typescript": "^4.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/react-is": { "version": "17.0.1", "dev": true, @@ -24352,6 +25050,12 @@ "version": "0.4.1", "license": "MIT" }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, "node_modules/spawn-wrap": { "version": "2.0.0", "license": "ISC", @@ -25183,6 +25887,12 @@ "version": "0.2.1", "license": "MIT" }, + "node_modules/string-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz", + "integrity": "sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=", + "dev": true + }, "node_modules/string-length": { "version": "4.0.2", "dev": true, @@ -26207,7 +26917,6 @@ }, "node_modules/tslib": { "version": "2.1.0", - "dev": true, "license": "0BSD" }, "node_modules/tsutils": { @@ -26331,9 +27040,8 @@ }, "node_modules/typescript": { "version": "4.2.3", - "dev": true, + "devOptional": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -26894,6 +27602,18 @@ "dev": true, "license": "MIT" }, + "node_modules/vue": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.1.4.tgz", + "integrity": "sha512-p8dcdyeCgmaAiZsbLyDkmOLcFGZb/jEVdCLW65V68LRCXTNX8jKsgah2F7OZ/v/Ai2V0Fb1MNO0vz/GFqsPVMA==", + "dev": true, + "peer": true, + "dependencies": { + "@vue/compiler-dom": "3.1.4", + "@vue/runtime-dom": "3.1.4", + "@vue/shared": "3.1.4" + } + }, "node_modules/w3c-hr-time": { "version": "1.0.2", "dev": true, @@ -30068,6 +30788,190 @@ "@babel/plugin-syntax-optional-chaining": "^7.0.0" } }, + "@formatjs/cli": { + "version": "4.2.27", + "resolved": "https://registry.npmjs.org/@formatjs/cli/-/cli-4.2.27.tgz", + "integrity": "sha512-P+y3nIBa+IMfv8dKPdZ38xhF/l9AghsU8kKi2onUJLpvjjDdjTEUTleaPpVghZKhe6BqNbso+anludxlZUdKoA==", + "dev": true, + "requires": { + "@formatjs/icu-messageformat-parser": "2.0.7", + "@formatjs/ts-transformer": "3.4.5", + "@types/json-stable-stringify": "^1.0.32", + "@types/lodash": "^4.14.150", + "@types/node": "14", + "@vue/compiler-core": "^3.0.0", + "@vue/compiler-sfc": "^3.0.5", + "chalk": "^4.0.0", + "commander": "8", + "fast-glob": "^3.2.4", + "fs-extra": "^9.0.0", + "json-stable-stringify": "^1.0.1", + "lodash": "^4.17.15", + "loud-rejection": "^2.2.0", + "tslib": "^2.1.0", + "typescript": "^4.0" + }, + "dependencies": { + "@formatjs/ts-transformer": { + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/@formatjs/ts-transformer/-/ts-transformer-3.4.5.tgz", + "integrity": "sha512-VzjT9jbpizZhwvtX/jaoTOeHQ/nvEx9ttzDrRXcFIGXyxupBZKTxr/+v6j3NjUmeiuN3JfaXhZUYmG+zsS0kxw==", + "dev": true, + "requires": { + "@formatjs/icu-messageformat-parser": "2.0.7", + "chalk": "^4.1.1", + "tslib": "^2.1.0" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "commander": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.0.0.tgz", + "integrity": "sha512-Xvf85aAtu6v22+E5hfVoLHqyul/jyxh91zvqk/ioJTQuJR7Z78n7H558vMPKanPSRgIEeZemT92I2g9Y8LPbSQ==", + "dev": true + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "@formatjs/ecma402-abstract": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.9.4.tgz", + "integrity": "sha512-ePJXI7tWC9PBxQxS7jtbkCLGVmpC8MH8n9Yjmg8dsh9wXK9svu7nAbq76Oiu5Zb+5GVkLkeTVerlSvHCbNImlA==", + "requires": { + "tslib": "^2.1.0" + } + }, + "@formatjs/fast-memoize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-1.1.1.tgz", + "integrity": "sha512-mIqBr5uigIlx13eZTOPSEh2buDiy3BCdMYUtewICREQjbb4xarDiVWoXSnrERM7NanZ+0TAHNXSqDe6HpEFQUg==" + }, + "@formatjs/icu-messageformat-parser": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.0.7.tgz", + "integrity": "sha512-gduYfh/YdBTmb1XzLueNaofiGZVMrkaDg0RSa0GNztKWs4QXIRS+28cjcuWNpV0q5S8aiLMkP7SHQpZKnPCHLw==", + "requires": { + "@formatjs/ecma402-abstract": "1.9.4", + "@formatjs/icu-skeleton-parser": "1.2.8", + "tslib": "^2.1.0" + } + }, + "@formatjs/icu-skeleton-parser": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.2.8.tgz", + "integrity": "sha512-KLSSAA7Q2Uv7msij8saaOE5rpsHK/2WkfS3737JnDyVTFOYe8l2OarIBUoTC5gi1BnCgiN/1icZlqXwyUX6obA==", + "requires": { + "@formatjs/ecma402-abstract": "1.9.4", + "tslib": "^2.1.0" + } + }, + "@formatjs/intl": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-1.13.2.tgz", + "integrity": "sha512-aonTXXaI/Guqr4t87m/XWfmgE9aPefDTLRnCwadxBDkUHw1/HQeUV+lp/3BgiPZfemIdBq9UgdigDCwrpEwrTA==", + "requires": { + "@formatjs/ecma402-abstract": "1.9.4", + "@formatjs/fast-memoize": "1.1.1", + "@formatjs/icu-messageformat-parser": "2.0.7", + "@formatjs/intl-displaynames": "5.1.6", + "@formatjs/intl-listformat": "6.2.6", + "intl-messageformat": "9.7.1", + "tslib": "^2.1.0" + } + }, + "@formatjs/intl-displaynames": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/@formatjs/intl-displaynames/-/intl-displaynames-5.1.6.tgz", + "integrity": "sha512-s0eDyQFM2gQIPgn+MyaH+UcCvp6ui2ft9UW1gsIkjBkaprRlzKMd3fjxcUFO/I7oyXXA6FYR4qHR8u1I0+PvXA==", + "requires": { + "@formatjs/ecma402-abstract": "1.9.4", + "tslib": "^2.1.0" + } + }, + "@formatjs/intl-listformat": { + "version": "6.2.6", + "resolved": "https://registry.npmjs.org/@formatjs/intl-listformat/-/intl-listformat-6.2.6.tgz", + "integrity": "sha512-6FMdQY1+QKqJW5IhsVPFuEaR/uRiBKP+Y1oDvamZKzDfJ2vQmk9jqSF51VztlZH8XSfdO0IgvBzeRPHahKChQA==", + "requires": { + "@formatjs/ecma402-abstract": "1.9.4", + "tslib": "^2.1.0" + } + }, "@fortawesome/fontawesome-free": { "version": "5.15.3" }, @@ -30846,6 +31750,15 @@ "@babel/types": "^7.0.0" } }, + "@types/babel__helper-plugin-utils": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@types/babel__helper-plugin-utils/-/babel__helper-plugin-utils-7.10.0.tgz", + "integrity": "sha512-60YtHzhQ9HAkToHVV+TB4VLzBn9lrfgrsOjiJMtbv/c1jPdekBxaByd6DMsGBzROXWoIL6U3lEFvvbu69RkUoA==", + "dev": true, + "requires": { + "@types/babel__core": "*" + } + }, "@types/babel__template": { "version": "7.4.0", "dev": true, @@ -30870,7 +31783,9 @@ } }, "@types/estree": { - "version": "0.0.47", + "version": "0.0.48", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.48.tgz", + "integrity": "sha512-LfZwXoGUDo0C3me81HXgkBg5CTQYb6xzEl+fNmbO4JdRiSKQ8A0GD1OBBvKAIsbCUgoyAty7m99GqqMQe784ew==", "dev": true }, "@types/glob": { @@ -30888,6 +31803,15 @@ "@types/node": "*" } }, + "@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "requires": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "@types/html-minifier-terser": { "version": "5.1.1", "dev": true @@ -30914,9 +31838,21 @@ "version": "7.0.7", "dev": true }, + "@types/json-stable-stringify": { + "version": "1.0.33", + "resolved": "https://registry.npmjs.org/@types/json-stable-stringify/-/json-stable-stringify-1.0.33.tgz", + "integrity": "sha512-qEWiQff6q2tA5gcJGWwzplQcXdJtm+0oy6IHGHzlOf3eFAkGE/FIPXZK9ofWgNSHVp8AFFI33PJJshS0ei3Gvw==", + "dev": true + }, "@types/json5": { "version": "0.0.29" }, + "@types/lodash": { + "version": "4.14.171", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.171.tgz", + "integrity": "sha512-7eQ2xYLLI/LsicL2nejW9Wyko3lcpN6O/z0ZLHrEQsg280zIdCv1t/0m6UtBjUHokCGBQ3gYTbHzDkZ1xOBwwg==", + "dev": true + }, "@types/minimatch": { "version": "3.0.3", "dev": true @@ -30938,8 +31874,7 @@ "dev": true }, "@types/prop-types": { - "version": "15.7.3", - "dev": true + "version": "15.7.3" }, "@types/q": { "version": "1.5.4", @@ -30947,7 +31882,6 @@ }, "@types/react": { "version": "17.0.3", - "dev": true, "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -30962,8 +31896,7 @@ } }, "@types/scheduler": { - "version": "0.16.1", - "dev": true + "version": "0.16.1" }, "@types/source-list-map": { "version": "0.1.2", @@ -31176,6 +32109,143 @@ "lodash.throttle": "^4.1.1" } }, + "@vue/compiler-core": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.1.4.tgz", + "integrity": "sha512-TnUz+1z0y74O/A4YKAbzsdUfamyHV73MihrEfvettWpm9bQKVoZd1nEmR1cGN9LsXWlwAvVQBetBlWdOjmQO5Q==", + "dev": true, + "requires": { + "@babel/parser": "^7.12.0", + "@babel/types": "^7.12.0", + "@vue/shared": "3.1.4", + "estree-walker": "^2.0.1", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@vue/compiler-dom": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.1.4.tgz", + "integrity": "sha512-3tG2ScHkghhUBuFwl9KgyZhrS8CPFZsO7hUDekJgIp5b1OMkROr4AvxHu6rRMl4WkyvYkvidFNBS2VfOnwa6Kw==", + "dev": true, + "requires": { + "@vue/compiler-core": "3.1.4", + "@vue/shared": "3.1.4" + } + }, + "@vue/compiler-sfc": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.1.4.tgz", + "integrity": "sha512-4KDQg60Khy3SgnF+V/TB2NZqzmM4TyGRmzsxqG1SebGdMSecCweFDSlI/F1vDYk6dKiCHgmpoT9A1sLxswkJ0A==", + "dev": true, + "requires": { + "@babel/parser": "^7.13.9", + "@babel/types": "^7.13.0", + "@types/estree": "^0.0.48", + "@vue/compiler-core": "3.1.4", + "@vue/compiler-dom": "3.1.4", + "@vue/compiler-ssr": "3.1.4", + "@vue/shared": "3.1.4", + "consolidate": "^0.16.0", + "estree-walker": "^2.0.1", + "hash-sum": "^2.0.0", + "lru-cache": "^5.1.1", + "magic-string": "^0.25.7", + "merge-source-map": "^1.1.0", + "postcss": "^8.1.10", + "postcss-modules": "^4.0.0", + "postcss-selector-parser": "^6.0.4", + "source-map": "^0.6.1" + }, + "dependencies": { + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } + }, + "@vue/compiler-ssr": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.1.4.tgz", + "integrity": "sha512-Box8fCuCFPp0FuimIswjDkjwiSDCBkHvt/xVALyFkYCiIMWv2eR53fIjmlsnEHhcBuZ+VgRC+UanCTcKvSA1gA==", + "dev": true, + "requires": { + "@vue/compiler-dom": "3.1.4", + "@vue/shared": "3.1.4" + } + }, + "@vue/reactivity": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.4.tgz", + "integrity": "sha512-YDlgii2Cr9yAoKVZFzgY4j0mYlVT73986X3e5SPp6ifqckSEoFSUWXZK2Tb53TB/9qO29BEEbspnKD3m3wAwkA==", + "dev": true, + "peer": true, + "requires": { + "@vue/shared": "3.1.4" + } + }, + "@vue/runtime-core": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.1.4.tgz", + "integrity": "sha512-qmVJgJuFxfT7M4qHQ4M6KqhKC66fjuswK+aBivE8dWiZ2rtIGl9gtJGpwqwjQEcKEBTOfvvrtrwBncYArJUO8Q==", + "dev": true, + "peer": true, + "requires": { + "@vue/reactivity": "3.1.4", + "@vue/shared": "3.1.4" + } + }, + "@vue/runtime-dom": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.1.4.tgz", + "integrity": "sha512-vbmwgTxku1BU87Kw7r29adv0OIrDXCW0PslOPQT0O/9R5SqcXgS94Yj6zsztDjvghegenwIAPNLlDR1Auh5s+w==", + "dev": true, + "peer": true, + "requires": { + "@vue/runtime-core": "3.1.4", + "@vue/shared": "3.1.4", + "csstype": "^2.6.8" + }, + "dependencies": { + "csstype": { + "version": "2.6.17", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.17.tgz", + "integrity": "sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A==", + "dev": true, + "peer": true + } + } + }, + "@vue/shared": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.4.tgz", + "integrity": "sha512-6O45kZAmkLvzGLToBxEz4lR2W6kXohCtebV2UxjH9GXjd8X9AhEn68FN9eNanFtWNzvgw1hqd6HkPRVQalqf7Q==", + "dev": true + }, "@webassemblyjs/ast": { "version": "1.9.0", "dev": true, @@ -31689,6 +32759,12 @@ "array-filter": { "version": "1.0.0" }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, "array-flatten": { "version": "2.1.2", "dev": true @@ -32072,6 +33148,86 @@ "fbjs": "^1.0.0" } }, + "babel-plugin-formatjs": { + "version": "10.3.2", + "resolved": "https://registry.npmjs.org/babel-plugin-formatjs/-/babel-plugin-formatjs-10.3.2.tgz", + "integrity": "sha512-u1A6/PpwGD4xb3X+egEb6BQ2QbumHFgJYduGCxMiRhONfEsVeD2SdvDlOsS1CWOr/03SFIB/U5j+QbUM1lh7sw==", + "dev": true, + "requires": { + "@babel/core": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-jsx": "7", + "@babel/traverse": "7", + "@babel/types": "^7.9.5", + "@formatjs/icu-messageformat-parser": "2.0.7", + "@formatjs/ts-transformer": "3.4.5", + "@types/babel__core": "^7.1.7", + "@types/babel__helper-plugin-utils": "7", + "tslib": "^2.1.0" + }, + "dependencies": { + "@formatjs/ts-transformer": { + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/@formatjs/ts-transformer/-/ts-transformer-3.4.5.tgz", + "integrity": "sha512-VzjT9jbpizZhwvtX/jaoTOeHQ/nvEx9ttzDrRXcFIGXyxupBZKTxr/+v6j3NjUmeiuN3JfaXhZUYmG+zsS0kxw==", + "dev": true, + "requires": { + "@formatjs/icu-messageformat-parser": "2.0.7", + "chalk": "^4.1.1", + "tslib": "^2.1.0" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "babel-plugin-istanbul": { "version": "6.0.0", "dev": true, @@ -33499,6 +34655,15 @@ "version": "1.2.0", "dev": true }, + "consolidate": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.16.0.tgz", + "integrity": "sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ==", + "dev": true, + "requires": { + "bluebird": "^3.7.2" + } + }, "constants-browserify": { "version": "1.0.0", "dev": true @@ -34136,12 +35301,20 @@ } }, "csstype": { - "version": "3.0.7", - "dev": true + "version": "3.0.7" }, "cuid": { "version": "2.1.8" }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, "custom-error-instance": { "version": "2.1.1" }, @@ -35324,6 +36497,12 @@ "estraverse": { "version": "4.3.0" }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, "esutils": { "version": "2.0.3" }, @@ -36274,6 +37453,37 @@ "functional-red-black-tree": { "version": "1.0.1" }, + "generic-names": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generic-names/-/generic-names-2.0.1.tgz", + "integrity": "sha512-kPCHWa1m9wGG/OwQpeweTwM/PYiQLrUIxXbt/P4Nic3LbGjCP0YwrALHW1uNLKZ0LIMg+RF+XRlj2ekT9ZlZAQ==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + } + } + }, "gensync": { "version": "1.0.0-beta.2" }, @@ -36545,6 +37755,12 @@ "safe-buffer": "^5.2.0" } }, + "hash-sum": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", + "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==", + "dev": true + }, "hash.js": { "version": "1.1.7", "requires": { @@ -36910,6 +38126,12 @@ "safer-buffer": ">= 2.1.2 < 3.0.0" } }, + "icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", + "dev": true + }, "icss-utils": { "version": "5.1.0", "dev": true, @@ -37092,6 +38314,16 @@ "interpret": { "version": "1.4.0" }, + "intl-messageformat": { + "version": "9.7.1", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.7.1.tgz", + "integrity": "sha512-DNiuD+/59G9qaYu3U0KgwCV0zpN9XRoUvc8izSNCNAA5MknhiIUONFE0WtScP+E/7JfoENu+CX57P/SURRbI0A==", + "requires": { + "@formatjs/fast-memoize": "1.1.1", + "@formatjs/icu-messageformat-parser": "2.0.7", + "tslib": "^2.1.0" + } + }, "invariant": { "version": "2.2.4", "requires": { @@ -39715,6 +40947,12 @@ "lodash._basetostring": "~4.12.0" } }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "dev": true + }, "lodash.debounce": { "version": "4.0.8", "dev": true @@ -39817,6 +41055,16 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "loud-rejection": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-2.2.0.tgz", + "integrity": "sha512-S0FayMXku80toa5sZ6Ro4C+s+EtFDCsyJNG/AzFMfX3AxD5Si4dZsgzm/kKnbOxHl5Cv8jBlno8+3XYIh2pNjQ==", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.2" + } + }, "lower-case": { "version": "2.0.2", "dev": true, @@ -39839,6 +41087,15 @@ "version": "1.4.4", "dev": true }, + "magic-string": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.4" + } + }, "make-dir": { "version": "2.1.0", "dev": true, @@ -39953,6 +41210,23 @@ "version": "1.0.1", "dev": true }, + "merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, "merge-stream": { "version": "2.0.0", "dev": true @@ -42490,6 +43764,22 @@ } } }, + "postcss-modules": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/postcss-modules/-/postcss-modules-4.1.3.tgz", + "integrity": "sha512-dBT39hrXe4OAVYJe/2ZuIZ9BzYhOe7t+IhedYeQ2OxKwDpAGlkEN/fR0fGnrbx4BvgbMReRX4hCubYK9cE/pJQ==", + "dev": true, + "requires": { + "generic-names": "^2.0.1", + "icss-replace-symbols": "^1.1.0", + "lodash.camelcase": "^4.3.0", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "string-hash": "^1.1.1" + } + }, "postcss-modules-extract-imports": { "version": "3.0.0", "dev": true, @@ -44126,6 +45416,22 @@ "version": "4.0.3", "requires": {} }, + "react-intl": { + "version": "5.20.4", + "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-5.20.4.tgz", + "integrity": "sha512-lYUL8hWkRHbpVtedGSjpQ1kK/x2AAGZHGgOHsU0SFDufHo2aS7xdvRcaxXD3PMVDuh53KcU+vTaun+bcrwKpbA==", + "requires": { + "@formatjs/ecma402-abstract": "1.9.4", + "@formatjs/icu-messageformat-parser": "2.0.7", + "@formatjs/intl": "1.13.2", + "@formatjs/intl-displaynames": "5.1.6", + "@formatjs/intl-listformat": "6.2.6", + "@types/hoist-non-react-statics": "^3.3.1", + "hoist-non-react-statics": "^3.3.2", + "intl-messageformat": "9.7.1", + "tslib": "^2.1.0" + } + }, "react-is": { "version": "17.0.1", "dev": true @@ -45431,6 +46737,12 @@ "source-map-url": { "version": "0.4.1" }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, "spawn-wrap": { "version": "2.0.0", "requires": { @@ -46026,6 +47338,12 @@ "string-convert": { "version": "0.2.1" }, + "string-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz", + "integrity": "sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=", + "dev": true + }, "string-length": { "version": "4.0.2", "dev": true, @@ -46698,8 +48016,7 @@ } }, "tslib": { - "version": "2.1.0", - "dev": true + "version": "2.1.0" }, "tsutils": { "version": "3.21.0", @@ -46787,8 +48104,7 @@ }, "typescript": { "version": "4.2.3", - "dev": true, - "peer": true + "devOptional": true }, "ua-parser-js": { "version": "0.7.24" @@ -47179,6 +48495,18 @@ "version": "1.1.2", "dev": true }, + "vue": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.1.4.tgz", + "integrity": "sha512-p8dcdyeCgmaAiZsbLyDkmOLcFGZb/jEVdCLW65V68LRCXTNX8jKsgah2F7OZ/v/Ai2V0Fb1MNO0vz/GFqsPVMA==", + "dev": true, + "peer": true, + "requires": { + "@vue/compiler-dom": "3.1.4", + "@vue/runtime-dom": "3.1.4", + "@vue/shared": "3.1.4" + } + }, "w3c-hr-time": { "version": "1.0.2", "dev": true, diff --git a/web/cashtab/package.json b/web/cashtab/package.json --- a/web/cashtab/package.json +++ b/web/cashtab/package.json @@ -14,7 +14,6 @@ "dotenv-expand": "^5.1.0", "ecashaddrjs": "^1.0.1", "ethereum-blockies-base64": "^1.0.2", - "fbt": "^0.16.4", "localforage": "^1.9.0", "lodash.isempty": "^4.4.0", "lodash.isequal": "^4.5.0", @@ -28,6 +27,7 @@ "react-dom": "^17.0.1", "react-ga": "^3.3.0", "react-image": "^4.0.3", + "react-intl": "^5.20.4", "react-router": "^5.2.0", "react-router-dom": "^5.2.0", "styled-components": "^4.4.0" @@ -39,23 +39,17 @@ ] }, "scripts": { - "manifest-fbts": "NODE_ENV=production node node_modules/babel-plugin-fbt/dist/bin/manifest --src src", - "collect-fbts": "NODE_ENV=production node node_modules/babel-plugin-fbt/dist/bin/collectFbt --pretty --manifest < .src_manifest.json > .source_strings.json", - "translate-fbts": "NODE_ENV=production node node_modules/babel-plugin-fbt/dist/bin/translate.js --pretty --translations translations/*.json --jenkins > src/translatedFbts.json", - "translate-fbts-single-file": "NODE_ENV=production node node_modules/babel-plugin-fbt/dist/bin/translate.js --pretty --jenkins --stdin < translation_input.json > src/translatedFbts.json", - "clean-fbts": "rm .enum_manifest.json .src_manifest.json .source_strings.json src/translatedFbts.json 2&> /dev/null || exit 0", - "fbt-generate-translations": "NODE_ENV=production node node_modules/fbt-generate-translations --locales src/i18n/locales.js --multi-files translations", - "fbt-generate-translations-single-file": "NODE_ENV=production node node_modules/fbt-generate-translations --locales src/i18n/locales.js", - "prepare-fbts": "NODE_ENV=production npm run manifest-fbts && npm run collect-fbts && npm run fbt-generate-translations && npm run translate-fbts", - "prestart": "npm run prepare-fbts", - "prebuild": "npm run prepare-fbts", + "prestart": "npm run compile", + "prebuild": "npm run compile", "start": "node scripts/start.js", "build": "node scripts/build.js", "extension": "./scripts/extension.sh", "predeploy": "npm run build", "test": "node scripts/test.js", "test:coverage": "CI=true npm run test --coverage", - "debug": "node --inspect-brk=9229 scripts/start.js" + "debug": "node --inspect-brk=9229 scripts/start.js", + "extract": "formatjs extract src/**/*.{js,jsx} --out-file lang/en-us.json --id-interpolation-pattern '[sha512:contenthash:base64:6]' --format transifex", + "compile": "formatjs compile-folder --ast --format transifex lang src/compiled-lang" }, "eslintConfig": { "extends": "react-app" @@ -138,12 +132,22 @@ "babel": { "presets": [ "react-app" + ], + "plugins": [ + [ + "formatjs", + { + "idInterpolationPattern": "[sha512:contenthash:base64:6]", + "ast": true + } + ] ] }, "devDependencies": { "@ant-design/dark-theme": "^1.0.3", "@babel/core": "^7.6.0", "@babel/node": "^7.12.6", + "@formatjs/cli": "^4.2.27", "@psf/bch-js": "^4.16.1", "@svgr/webpack": "^5.5.0", "@testing-library/react": "^11.2.2", @@ -151,8 +155,7 @@ "babel-eslint": "^10.0.3", "babel-jest": "^26.6.3", "babel-loader": "^8.0.6", - "babel-plugin-fbt": "^0.19.1", - "babel-plugin-fbt-runtime": "^0.9.16", + "babel-plugin-formatjs": "^10.3.2", "babel-plugin-named-asset-import": "^0.3.7", "babel-preset-react-app": "^10.0.0", "camelcase": "^5.3.1", @@ -167,7 +170,6 @@ "eslint-plugin-react-hooks": "^4.2.0", "eslint-webpack-plugin": "^2.5.4", "extensionizer": "^1.0.1", - "fbt-generate-translations": "^0.0.4", "file-loader": "^6.2.0", "fs-extra": "^7.0.1", "html-webpack-plugin": "^4.5.1", diff --git a/web/cashtab/src/i18n/init.js b/web/cashtab/src/i18n/init.js deleted file mode 100644 --- a/web/cashtab/src/i18n/init.js +++ /dev/null @@ -1,15 +0,0 @@ -import { init } from 'fbt'; -import translations from '../translatedFbts.json'; -import locales from './locales'; -const viewerContext = { - locale: navigator.language.replace('-', '_'), -}; - -init({ - translations, - hooks: { - getViewerContext: () => viewerContext, - }, - locales, - defaultLocale: navigator.language, -}); diff --git a/web/cashtab/src/i18n/locales.js b/web/cashtab/src/i18n/locales.js deleted file mode 100644 --- a/web/cashtab/src/i18n/locales.js +++ /dev/null @@ -1,14 +0,0 @@ -module.exports = { - en_US: { - bcp47: 'en-US', - displayName: 'English (US)', - englishName: 'English (US)', - rtl: false, - }, - pt_BR: { - bcp47: 'pt-BR', - displayName: 'Português (Brasil)', - englishName: 'Portuguese (Brazilian)', - rtl: false, - }, -}; diff --git a/web/cashtab/src/index.js b/web/cashtab/src/index.js --- a/web/cashtab/src/index.js +++ b/web/cashtab/src/index.js @@ -5,16 +5,31 @@ import { WalletProvider } from './utils/context'; import { HashRouter as Router } from 'react-router-dom'; import GA from './utils/GoogleAnalytics'; +import { IntlProvider } from 'react-intl'; +import loadLocaleData from './utils/loadLocaleData'; -ReactDOM.render( - - - {GA.init() && } - - - , - document.getElementById('root'), -); +async function bootstrapApplication() { + let messages; + let locale = navigator.language.toLowerCase(); + try { + messages = await loadLocaleData(locale); + } catch (e) { + console.error(e); + messages = await loadLocaleData('en-us'); + locale = 'en-us'; + } + ReactDOM.render( + + + + {GA.init() && } + + + + , + document.getElementById('root'), + ); +} if ('serviceWorker' in navigator) { window.addEventListener('load', () => @@ -25,3 +40,5 @@ if (module.hot) { module.hot.accept(); } + +bootstrapApplication(); diff --git a/web/cashtab/src/utils/loadLocaleData.js b/web/cashtab/src/utils/loadLocaleData.js new file mode 100644 --- /dev/null +++ b/web/cashtab/src/utils/loadLocaleData.js @@ -0,0 +1,3 @@ +export default function loadLocaleData(locale) { + return import(`../compiled-lang/${locale}.json`); +} diff --git a/web/cashtab/translations/en_US.json b/web/cashtab/translations/en_US.json deleted file mode 100644 --- a/web/cashtab/translations/en_US.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "fb-locale": "en_US", - "translations": { - "t+5SwD1ho9xhYy5PlfAPGg==": { - "translations": [ - { - "translation": "Wallet" - } - ] - }, - "fXmXHZxGc0NA87a+A1ppng==": { - "translations": [ - { - "translation": "Send" - } - ] - }, - "M8PvPwXAFjS9vGdEg8xnWw==": { - "translations": [ - { - "translation": "Settings" - } - ] - } - } -} \ No newline at end of file diff --git a/web/cashtab/translations/pt_BR.json b/web/cashtab/translations/pt_BR.json deleted file mode 100644 --- a/web/cashtab/translations/pt_BR.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "fb-locale": "pt_BR", - "translations": { - "t+5SwD1ho9xhYy5PlfAPGg==": { - "translations": [ - { - "translation": "Carteira" - } - ] - }, - "fXmXHZxGc0NA87a+A1ppng==": { - "translations": [ - { - "translation": "Enviar" - } - ] - }, - "M8PvPwXAFjS9vGdEg8xnWw==": { - "translations": [ - { - "translation": "Opções" - } - ] - } - } -} \ No newline at end of file