diff --git a/configs/webpack.config.main.ts b/configs/webpack.config.main.ts index 8222c6fc..1829f96a 100644 --- a/configs/webpack.config.main.ts +++ b/configs/webpack.config.main.ts @@ -5,6 +5,9 @@ export const config: webpack.Configuration = { mode: 'development', entry: join(__dirname, '../src/client-electron/main/main.ts'), target: 'electron-main', + resolve: { + extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'], + }, output: { path: join(__dirname, '../dist'), filename: 'main.js', diff --git a/configs/webpack.config.renderer.ts b/configs/webpack.config.renderer.ts index 0fbd2539..19b30bc5 100644 --- a/configs/webpack.config.renderer.ts +++ b/configs/webpack.config.renderer.ts @@ -1,4 +1,5 @@ import HtmlWebpackPlugin from 'html-webpack-plugin'; +import { TsconfigPathsPlugin } from 'tsconfig-paths-webpack-plugin'; import { join } from 'path'; import webpack from 'webpack'; @@ -12,6 +13,7 @@ export const config: webpack.Configuration = { }, resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'], + plugins: [new TsconfigPathsPlugin()], }, module: { rules: [ @@ -20,10 +22,6 @@ export const config: webpack.Configuration = { exclude: /node_modules/, loader: 'ts-loader', }, - { - test: /\.s[ac]ss$/, - use: ['style-loader', 'css-loader', 'sass-loader'], - }, { test: /\.ttf$/, loader: 'file-loader', diff --git a/package-lock.json b/package-lock.json index fcd732ef..3a0b6837 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -54,7 +53,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", - "dev": true, "requires": { "@babel/types": "^7.12.11", "jsesc": "^2.5.1", @@ -64,8 +62,26 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz", + "integrity": "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==", + "requires": { + "@babel/types": "^7.12.13" + }, + "dependencies": { + "@babel/types": { + "version": "7.13.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.17.tgz", + "integrity": "sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA==", + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "to-fast-properties": "^2.0.0" + } } } }, @@ -73,7 +89,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", - "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.12.10", "@babel/template": "^7.12.7", @@ -84,7 +99,6 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", - "dev": true, "requires": { "@babel/types": "^7.12.10" } @@ -102,7 +116,6 @@ "version": "7.12.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", - "dev": true, "requires": { "@babel/types": "^7.12.5" } @@ -164,7 +177,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", - "dev": true, "requires": { "@babel/types": "^7.12.11" } @@ -172,8 +184,7 @@ "@babel/helper-validator-identifier": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" }, "@babel/helpers": { "version": "7.12.5", @@ -190,7 +201,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", @@ -201,7 +211,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -210,7 +219,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -221,7 +229,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -229,20 +236,17 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -252,8 +256,7 @@ "@babel/parser": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", - "dev": true + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==" }, "@babel/plugin-syntax-async-generators": { "version": "7.8.4", @@ -367,7 +370,6 @@ "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", - "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/parser": "^7.12.7", @@ -378,7 +380,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", - "dev": true, "requires": { "@babel/code-frame": "^7.12.11", "@babel/generator": "^7.12.11", @@ -395,7 +396,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -489,6 +489,29 @@ "fs-extra": "^9.0.1" } }, + "@emotion/is-prop-valid": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "requires": { + "@emotion/memoize": "0.7.4" + } + }, + "@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==" + }, + "@emotion/stylis": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", + "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" + }, + "@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1091,6 +1114,16 @@ "@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==", + "dev": true, + "requires": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "@types/html-minifier-terser": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", @@ -1265,6 +1298,17 @@ "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, + "@types/styled-components": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.9.tgz", + "integrity": "sha512-kbEG6YlwK8rucITpKEr6pA4Ho9KSQHUUOzZ9lY3va1mtcjvS3D0wDciFyHEiNHKLL/npZCKDQJqm0x44sPO9oA==", + "dev": true, + "requires": { + "@types/hoist-non-react-statics": "*", + "@types/react": "*", + "csstype": "^3.0.2" + } + }, "@types/through": { "version": "0.0.30", "resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.30.tgz", @@ -1274,6 +1318,12 @@ "@types/node": "*" } }, + "@types/uuid": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.0.tgz", + "integrity": "sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ==", + "dev": true + }, "@types/verror": { "version": "1.10.4", "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.4.tgz", @@ -1553,6 +1603,32 @@ "uri-js": "^4.2.2" } }, + "ajv-formats": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.0.2.tgz", + "integrity": "sha512-Brah4Uo5/U8v76c6euTwtjVFFaVishwnJrQBYpev1JRh4vjA1F4HY3UzQez41YUCszUCXKagG8v6eVRBHV1gkw==", + "requires": { + "ajv": "^8.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.2.0.tgz", + "integrity": "sha512-WSNGFuyWd//XO8n/m/EaOlNLtO0yL8EXT/74LqT4khdhpZjP7lkj/kT5uwRmGitKEVp/Oj7ZUHeGfPtgHhQ5CA==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + } + } + }, "ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", @@ -2023,6 +2099,11 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true }, + "atomically": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz", + "integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==" + }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -2074,6 +2155,22 @@ "@types/babel__traverse": "^7.0.6" } }, + "babel-plugin-styled-components": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.12.0.tgz", + "integrity": "sha512-FEiD7l5ZABdJPpLssKXjBUJMYqzbcNzBowfXDCdJhOpbhWiewapUaY+LZGT8R4Jg2TwOjGjG4RKeyrO5p9sBkA==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-module-imports": "^7.0.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "lodash": "^4.17.11" + } + }, + "babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" + }, "babel-preset-current-node-syntax": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", @@ -2548,6 +2645,11 @@ "quick-lru": "^4.0.1" } }, + "camelize": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", + "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" + }, "caniuse-lite": { "version": "1.0.30001216", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001216.tgz", @@ -3169,6 +3271,57 @@ } } }, + "conf": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/conf/-/conf-10.0.1.tgz", + "integrity": "sha512-QClEoNcruwBL84QgMEPHibL3ERxWIrRKhbjJKG1VsFBadm5QpS0jsu4QjY/maxUvhyAKXeyrs+ws+lC6PajnEg==", + "requires": { + "ajv": "^8.1.0", + "ajv-formats": "^2.0.2", + "atomically": "^1.7.0", + "debounce-fn": "^4.0.0", + "dot-prop": "^6.0.1", + "env-paths": "^2.2.1", + "json-schema-typed": "^7.0.3", + "onetime": "^5.1.2", + "pkg-up": "^3.1.0", + "semver": "^7.3.5" + }, + "dependencies": { + "ajv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.2.0.tgz", + "integrity": "sha512-WSNGFuyWd//XO8n/m/EaOlNLtO0yL8EXT/74LqT4khdhpZjP7lkj/kT5uwRmGitKEVp/Oj7ZUHeGfPtgHhQ5CA==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "requires": { + "is-obj": "^2.0.0" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, "config-chain": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", @@ -3951,41 +4104,10 @@ "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", "dev": true }, - "css-loader": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.4.tgz", - "integrity": "sha512-OFYGyINCKkdQsTrSYxzGSFnGS4gNjcXkKkQgWxK138jgnPt+lepxdjSZNc8sHAl5vP3DhsJUxufWIjOwI8PMMw==", - "dev": true, - "requires": { - "camelcase": "^6.2.0", - "icss-utils": "^5.1.0", - "loader-utils": "^2.0.0", - "postcss": "^8.2.10", - "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", - "postcss-value-parser": "^4.1.0", - "schema-utils": "^3.0.0", - "semver": "^7.3.5" - }, - "dependencies": { - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } + "css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=" }, "css-select": { "version": "2.1.0", @@ -3999,18 +4121,22 @@ "nth-check": "^1.0.2" } }, + "css-to-react-native": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz", + "integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==", + "requires": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, "css-what": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", "dev": true }, - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true - }, "cssom": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", @@ -4085,11 +4211,25 @@ "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", "dev": true }, + "debounce-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz", + "integrity": "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==", + "requires": { + "mimic-fn": "^3.0.0" + }, + "dependencies": { + "mimic-fn": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==" + } + } + }, "debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, "requires": { "ms": "2.1.2" } @@ -5134,6 +5274,22 @@ "mime": "^2.5.0" } }, + "electron-store": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.0.0.tgz", + "integrity": "sha512-ZgRPUZkfrrjWSqxZeaxu7lEvmYf6tgl49dLMqxXGnEmliSiwv3u4rJPG+mH3fBQP9PBqgSh4TCuxHZImMMUgWg==", + "requires": { + "conf": "^10.0.0", + "type-fest": "^1.0.2" + }, + "dependencies": { + "type-fest": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.0.2.tgz", + "integrity": "sha512-a720oz3Kjbp3ll0zkeN9qjRhO7I34MKMhPGQiQJAmaZQZQ1lo+NWThK322f7sXV+kTg9B1Ybt16KgBXWgteT8w==" + } + } + }, "electron-to-chromium": { "version": "1.3.720", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.720.tgz", @@ -5200,8 +5356,7 @@ "env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==" }, "envinfo": { "version": "7.8.1", @@ -6390,8 +6545,7 @@ "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" }, "globalthis": { "version": "1.0.2", @@ -6590,6 +6744,21 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, "homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -6754,12 +6923,6 @@ "safer-buffer": ">= 2.1.2 < 3" } }, - "icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true - }, "idb-keyval": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-3.2.0.tgz", @@ -7167,8 +7330,7 @@ "is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" }, "is-object": { "version": "1.0.2", @@ -8445,8 +8607,7 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" }, "json-buffer": { "version": "3.0.0", @@ -8476,6 +8637,11 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, + "json-schema-typed": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz", + "integrity": "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==" + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -8546,12 +8712,6 @@ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true }, - "klona": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz", - "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==", - "dev": true - }, "latest-version": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", @@ -8688,8 +8848,7 @@ "lodash": { "version": "4.17.20", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", - "dev": true + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" }, "lodash._reinterpolate": { "version": "3.0.0", @@ -9083,20 +9242,13 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" }, - "nanoid": { - "version": "3.1.22", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.22.tgz", - "integrity": "sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ==", - "dev": true - }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -9839,7 +9991,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, "requires": { "p-try": "^2.0.0" } @@ -9865,8 +10016,7 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "package-json": { "version": "6.5.0", @@ -10151,6 +10301,46 @@ "find-up": "^4.0.0" } }, + "pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "requires": { + "find-up": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + } + } + }, "plist": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.2.tgz", @@ -10178,67 +10368,10 @@ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true }, - "postcss": { - "version": "8.2.13", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.13.tgz", - "integrity": "sha512-FCE5xLH+hjbzRdpbRb1IMCvPv9yZx2QnDarBEYSN0N0HYk+TcXsEhwdFcFb+SRWOKzKGErhIEbBK2ogyLdTtfQ==", - "dev": true, - "requires": { - "colorette": "^1.2.2", - "nanoid": "^3.1.22", - "source-map": "^0.6.1" - } - }, - "postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true - }, - "postcss-modules-local-by-default": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", - "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", - "dev": true, - "requires": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-modules-scope": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", - "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.4" - } - }, - "postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "dev": true, - "requires": { - "icss-utils": "^5.0.0" - } - }, - "postcss-selector-parser": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.5.tgz", - "integrity": "sha512-aFYPoYmXbZ1V6HZaSvat08M97A8HqO6Pjz+PiNpw/DhuRrC72XWAdp3hL6wusDCN31sSmcZyMGa2hZEuX+Xfhg==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - }, "postcss-value-parser": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", - "dev": true + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" }, "prebuild-install": { "version": "6.1.1", @@ -10607,6 +10740,11 @@ "scheduler": "^0.20.2" } }, + "react-icons": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.2.0.tgz", + "integrity": "sha512-rmzEDFt+AVXRzD7zDE21gcxyBizD/3NqjbX6cmViAgdqfJ2UiLer8927/QhhrXQV7dEj/1EGuOTPp7JnLYVJKQ==" + }, "react-is": { "version": "17.0.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", @@ -10880,6 +11018,11 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -11210,25 +11353,6 @@ "truncate-utf8-bytes": "^1.0.0" } }, - "sass": { - "version": "1.32.11", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.32.11.tgz", - "integrity": "sha512-O9tRcob/fegUVSIV1ihLLZcftIOh0AF1VpKgusUfLqnb2jQ0GLDwI5ivv1FYWivGv8eZ/AwntTyTzjcHu0c/qw==", - "dev": true, - "requires": { - "chokidar": ">=3.0.0 <4.0.0" - } - }, - "sass-loader": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-11.0.1.tgz", - "integrity": "sha512-Vp1LcP4slTsTNLEiDkTcm8zGN/XYYrZz2BZybQbliWA8eXveqA/AxsEjllQTpJbg2MzCsx/qNO48sHdZtOaxTw==", - "dev": true, - "requires": { - "klona": "^2.0.4", - "neo-async": "^2.6.2" - } - }, "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", @@ -11384,6 +11508,11 @@ "kind-of": "^6.0.2" } }, + "shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, "sharp": { "version": "0.28.1", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.28.1.tgz", @@ -12163,14 +12292,36 @@ "escape-string-regexp": "^1.0.2" } }, - "style-loader": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-2.0.0.tgz", - "integrity": "sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ==", - "dev": true, + "styled-components": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.2.3.tgz", + "integrity": "sha512-BlR+KrLW3NL1yhvEB+9Nu9Dt51CuOnHoxd+Hj+rYPdtyR8X11uIW9rvhpy3Dk4dXXBsiW1u5U78f00Lf/afGoA==", "requires": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" + "@babel/helper-module-imports": "^7.0.0", + "@babel/traverse": "^7.4.5", + "@emotion/is-prop-valid": "^0.8.8", + "@emotion/stylis": "^0.8.4", + "@emotion/unitless": "^0.7.4", + "babel-plugin-styled-components": ">= 1.12.0", + "css-to-react-native": "^3.0.0", + "hoist-non-react-statics": "^3.0.0", + "shallowequal": "^1.1.0", + "supports-color": "^5.5.0" + }, + "dependencies": { + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } } }, "sumchecker": { @@ -12452,8 +12603,7 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" }, "to-object-path": { "version": "0.3.0", @@ -13111,9 +13261,7 @@ "uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "optional": true + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, "v8-compile-cache": { "version": "2.3.0", diff --git a/package.json b/package.json index 7c1756d1..2dc9d531 100644 --- a/package.json +++ b/package.json @@ -64,10 +64,11 @@ "@types/react": "^17.0.4", "@types/react-dom": "^17.0.3", "@types/sharp": "^0.27.1", + "@types/styled-components": "^5.1.9", + "@types/uuid": "^8.3.0", "@types/webpack": "^5.28.0", "concurrently": "^5.3.0", "copy-webpack-plugin": "^8.1.1", - "css-loader": "^5.2.4", "electron": "^12.0.5", "electron-builder": "^22.10.5", "file-loader": "^6.2.0", @@ -77,10 +78,7 @@ "nexe": "^4.0.0-beta.18", "nodemon": "^2.0.7", "patch-package": "^6.4.7", - "sass": "^1.32.11", - "sass-loader": "^11.0.1", "standard-version": "^9.1.0", - "style-loader": "^2.0.0", "ts-jest": "^26.4.4", "ts-loader": "^9.1.1", "ts-node": "^9.1.1", @@ -96,6 +94,7 @@ "dependencies": { "@octokit/rest": "^18.4.0", "commander": "^7.2.0", + "electron-store": "^8.0.0", "inquirer": "^8.0.0", "iohook": "^0.6.6", "is-wsl": "^2.2.0", @@ -103,10 +102,13 @@ "ora": "^5.4.0", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-icons": "^4.2.0", "sanitize-filename": "^1.6.3", "screenshot-desktop": "^1.12.3", "sharp": "^0.28.1", "sound-play": "^1.1.0", - "tesseract.js": "^2.1.4" + "styled-components": "^5.2.3", + "tesseract.js": "^2.1.4", + "uuid": "^8.3.2" } } diff --git a/src/client-electron/common.ts b/src/client-electron/common.ts new file mode 100644 index 00000000..2ba3e290 --- /dev/null +++ b/src/client-electron/common.ts @@ -0,0 +1,80 @@ +import { IpcRendererEvent, ipcRenderer as ipc } from 'electron'; +import { ScreenshotDisplayOutput } from 'screenshot-desktop'; +import { v4 as uuidv4 } from 'uuid'; + +export enum WorkerStatus { + BOOTSTRAP, + READY, + WORKING, +} + +export interface HistoryEntry {} + +export interface AppSettings {} + +export interface State { + history: HistoryEntry[]; + displays: ScreenshotDisplayOutput[]; + activeDisplay: ScreenshotDisplayOutput; + settings: {}; + status: WorkerStatus; +} + +type Origin = 'worker' | 'renderer'; + +export interface Action<T = any> { + type: string; + payload?: T; + origin: Origin; +} + +export interface Request<T = any> { + type: string; + data?: T; + uuid: string; + origin: Origin; +} + +export interface Response<T = any> { + data: T; + uuid: string; + origin: Origin; +} + +export function createDispatcher(origin: Origin) { + return <TRes, TReq = any>(action: Omit<Request<TReq>, 'origin' | 'uuid'>) => + new Promise<TRes>((resolve) => { + const uuid = uuidv4(); + const req: Request<TReq> = { ...action, origin, uuid }; + + function onAsyncResponse(e: IpcRendererEvent, res: Response<TRes>) { + if (res.uuid !== uuid) return; + + ipc.removeListener('async-response', onAsyncResponse); + + resolve(res.data); + } + + ipc.on('async-response', onAsyncResponse); + ipc.send('async-request', req); + }); +} + +export const rendererDispatcher = createDispatcher('renderer'); + +export function createListener(origin: Origin) { + return (handler: (req: Request) => Promise<any>) => { + ipc.on('async-request', async (event, req: Request) => { + const data = await handler(req); + const res: Response = { data, uuid: req.uuid, origin }; + + event.sender.send('async-response', res); + }); + + return () => { + ipc.removeAllListeners('async-request'); + }; + }; +} + +export const workerListener = createListener('worker'); diff --git a/src/client-electron/main/main.ts b/src/client-electron/main/main.ts index 2c633050..aa1b332e 100644 --- a/src/client-electron/main/main.ts +++ b/src/client-electron/main/main.ts @@ -1,56 +1,26 @@ -import { app, BrowserWindow, globalShortcut, ipcMain as ipc } from 'electron'; -import { join } from 'path'; - -function createRendererWindow() { - const window = new BrowserWindow({ - minWidth: 1280, - minHeight: 720, - webPreferences: { - nodeIntegration: true, - contextIsolation: false, - }, - }); - - window.webContents.openDevTools(); - window.loadFile(join(__dirname, './renderer.html')); - - return window; -} - -function createWorkerWindow() { - const window = new BrowserWindow({ - show: false, - webPreferences: { - nodeIntegration: true, - contextIsolation: false, - backgroundThrottling: false, - }, - }); - - window.loadFile(join(__dirname, './worker.html')); - - return window; -} +import { app, globalShortcut, ipcMain as ipc } from 'electron'; +import { Store } from './store'; +import { createBrowserWindows } from './windows'; async function main() { await app.whenReady(); - const window = createRendererWindow(); - const worker = createWorkerWindow(); + const { worker, renderer } = createBrowserWindows(); + const store = new Store(worker.webContents, renderer.webContents); - window.on('closed', () => app.exit()); + renderer.on('closed', () => app.exit()); ipc.once('worker:ready', () => { - window.webContents.send('worker:ready'); - globalShortcut.register('CommandOrControl+numdec', () => { worker.webContents.send('worker:solve'); }); }); + + ipc.on('before-exit', () => { + store.dispose(); + + globalShortcut.unregisterAll(); + }); } main(); - -ipc.on('before-exit', () => { - globalShortcut.unregisterAll(); -}); diff --git a/src/client-electron/main/store.ts b/src/client-electron/main/store.ts new file mode 100644 index 00000000..9d3d86ba --- /dev/null +++ b/src/client-electron/main/store.ts @@ -0,0 +1,105 @@ +import { ipcMain as ipc, IpcMainEvent, WebContents } from 'electron'; +import ElectronStore from 'electron-store'; +import { + Action, + AppSettings, + HistoryEntry, + Request, + Response, + State, +} from '../common'; + +function reducer<T>({ type, payload }: Action<T>, state: State) { + switch (type) { + case 'SET_ACTIVE_DISPLAY': + return { + ...state, + activeDisplay: payload, + }; + case 'SET_DISPLAYS': + return { + ...state, + displays: payload, + }; + case 'SET_STATUS': + return { ...state, status: payload }; + } +} + +export class Store { + private settings = new ElectronStore<AppSettings>({ + name: 'settings', + defaults: {}, + }); + private history = new ElectronStore<{ data: HistoryEntry[] }>({ + name: 'history', + defaults: { data: [] }, + }); + + private state = this.getInitialState(); + + constructor(private worker: WebContents, private renderer: WebContents) { + this.registerStoreListeners(); + } + + private getInitialState(): State { + return { + history: this.history.get('data'), + displays: [], + activeDisplay: null, + settings: {}, + status: null, + }; + } + + private registerStoreListeners() { + ipc.on('state', this.onState.bind(this)); + ipc.on('get-state', this.onGetState.bind(this)); + ipc.on('async-request', this.onAsyncRequest.bind(this)); + } + + private onState(event: IpcMainEvent, action: Action) { + const dest = this.getDest(action); + this.state = reducer(action, this.state); + + dest.send('state', this.state); + dest.send(action.type, action.payload); + } + + private onGetState(event: IpcMainEvent) { + event.returnValue = this.state; + } + + private onAsyncRequest(event: IpcMainEvent, req: Request) { + function onAsyncResponse(e: IpcMainEvent, res: Response) { + if (res.uuid !== req.uuid) return; + + ipc.removeListener('async-response', onAsyncResponse); + + event.sender.send('async-response', res); + } + + ipc.on('async-response', onAsyncResponse); + + const dest = this.getDest(req); + + dest.send('async-request', req); + } + + private getDest(action: Action) { + return action.origin === 'worker' ? this.renderer : this.worker; + } + + getState() { + return this.state; + } + + dispose() { + this.history.set('data', this.state.history); + + ipc.removeAllListeners('state'); + ipc.removeAllListeners('async-request'); + ipc.removeAllListeners('async-response'); + ipc.removeAllListeners('get-state'); + } +} diff --git a/src/client-electron/main/windows.ts b/src/client-electron/main/windows.ts new file mode 100644 index 00000000..ed9f98b6 --- /dev/null +++ b/src/client-electron/main/windows.ts @@ -0,0 +1,37 @@ +import { BrowserWindow, BrowserWindowConstructorOptions } from 'electron'; +import { join } from 'path'; + +function createWindow(name: string, options: BrowserWindowConstructorOptions) { + const window = new BrowserWindow(options); + + window.loadFile(join(__dirname, `./${name}.html`)); + + return window; +} + +const workerOptions = { + show: false, + webPreferences: { + nodeIntegration: true, + contextIsolation: false, + backgroundThrottling: false, + }, +}; + +const rendererOptions = { + minWidth: 1280, + minHeight: 720, + webPreferences: { + nodeIntegration: true, + contextIsolation: false, + }, +}; + +export function createBrowserWindows() { + const worker = createWindow('worker', workerOptions); + const renderer = createWindow('renderer', rendererOptions); + + renderer.webContents.openDevTools(); + + return { worker, renderer }; +} diff --git a/src/client-electron/renderer/app.tsx b/src/client-electron/renderer/app.tsx index 78bfde32..436915af 100644 --- a/src/client-electron/renderer/app.tsx +++ b/src/client-electron/renderer/app.tsx @@ -1,5 +1,45 @@ -import { ipcRenderer as ipc } from 'electron'; +import { ipcRenderer as ipc, IpcRendererEvent } from 'electron'; +import { useEffect, useState } from 'react'; +import styled from 'styled-components'; +import { State } from '../common'; +import { StatusBar } from './components/StatusBar'; -ipc.once('worker:ready', () => console.log('worker ready')); +const Main = styled.main` + flex-grow: 1; +`; -export const App = () => <div className="app">BreachProtocolAutosolver</div>; +function useIpcEvent<T>(channel: string, initialValue?: T) { + const [value, setValue] = useState<T>(initialValue); + + useEffect(() => { + function handleEvent(e: IpcRendererEvent, value: T) { + setValue(value); + } + + ipc.on(channel, handleEvent); + + return () => { + ipc.removeListener(channel, handleEvent); + }; + }, []); + + return value; +} + +function useStore() { + const initialState = ipc.sendSync('get-state'); + const state = useIpcEvent<State>('state', initialState); + + return state; +} + +export const App = () => { + const state = useStore(); + + return ( + <> + <Main /> + <StatusBar display={state?.activeDisplay} status={state?.status} /> + </> + ); +}; diff --git a/src/client-electron/renderer/assets/fonts/Rajdhani/OFL.txt b/src/client-electron/renderer/assets/fonts/Rajdhani/OFL.txt new file mode 100755 index 00000000..6dd80965 --- /dev/null +++ b/src/client-electron/renderer/assets/fonts/Rajdhani/OFL.txt @@ -0,0 +1,93 @@ +Copyright (c) 2014, Indian Type Foundry (info@indiantypefoundry.com). + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/src/client-electron/renderer/assets/fonts/Rajdhani/Rajdhani-Bold.ttf b/src/client-electron/renderer/assets/fonts/Rajdhani/Rajdhani-Bold.ttf new file mode 100755 index 00000000..6c0454c0 Binary files /dev/null and b/src/client-electron/renderer/assets/fonts/Rajdhani/Rajdhani-Bold.ttf differ diff --git a/src/client-electron/renderer/assets/fonts/Rajdhani/Rajdhani-Light.ttf b/src/client-electron/renderer/assets/fonts/Rajdhani/Rajdhani-Light.ttf new file mode 100755 index 00000000..1c7a3613 Binary files /dev/null and b/src/client-electron/renderer/assets/fonts/Rajdhani/Rajdhani-Light.ttf differ diff --git a/src/client-electron/renderer/assets/fonts/Rajdhani/Rajdhani-Medium.ttf b/src/client-electron/renderer/assets/fonts/Rajdhani/Rajdhani-Medium.ttf new file mode 100755 index 00000000..e52b403e Binary files /dev/null and b/src/client-electron/renderer/assets/fonts/Rajdhani/Rajdhani-Medium.ttf differ diff --git a/src/client-electron/renderer/assets/fonts/Rajdhani/Rajdhani-Regular.ttf b/src/client-electron/renderer/assets/fonts/Rajdhani/Rajdhani-Regular.ttf new file mode 100755 index 00000000..37663a5c Binary files /dev/null and b/src/client-electron/renderer/assets/fonts/Rajdhani/Rajdhani-Regular.ttf differ diff --git a/src/client-electron/renderer/assets/fonts/Rajdhani/Rajdhani-SemiBold.ttf b/src/client-electron/renderer/assets/fonts/Rajdhani/Rajdhani-SemiBold.ttf new file mode 100755 index 00000000..f7ec9bb5 Binary files /dev/null and b/src/client-electron/renderer/assets/fonts/Rajdhani/Rajdhani-SemiBold.ttf differ diff --git a/src/client-electron/renderer/components/StatusBar.tsx b/src/client-electron/renderer/components/StatusBar.tsx new file mode 100644 index 00000000..bb8c7e7e --- /dev/null +++ b/src/client-electron/renderer/components/StatusBar.tsx @@ -0,0 +1,71 @@ +import { WorkerStatus } from '@/client-electron/common'; +import { FC } from 'react'; +import { MdDone } from 'react-icons/md'; +import { ScreenshotDisplayOutput } from 'screenshot-desktop'; +import styled from 'styled-components'; + +const Spacer = styled.div` + flex-grow: 1; +`; + +const StatusBarItem = styled.div` + height: 100%; + display: flex; + align-items: center; + display: inline-flex; + padding: 0 8px; +`; + +const InteractiveStatusBarItem = styled(StatusBarItem)` + user-select: none; + + &:hover { + color: var(--accent); + cursor: pointer; + } +`; + +const StatusBarStyled = styled.footer` + height: 40px; + background: var(--background); + color: #fff; + font-size: 18px; + font-weight: 500; + text-transform: uppercase; + padding: 0 12px; + gap: 0.5rem; + display: flex; +`; + +function renderStatusBarContent(status: WorkerStatus) { + switch (status) { + case WorkerStatus.BOOTSTRAP: + return <StatusBarItem>Loading...</StatusBarItem>; + case WorkerStatus.READY: + return <StatusBarItem>Ready</StatusBarItem>; + case WorkerStatus.WORKING: + return <StatusBarItem>Working...</StatusBarItem>; + default: + return <StatusBarItem>Initializing..</StatusBarItem>; + } +} + +// TODO: add missing props and replace placeholders. +interface StatusBarProps { + status: WorkerStatus; + display: ScreenshotDisplayOutput; +} + +export const StatusBar: FC<StatusBarProps> = ({ status, display }) => { + return ( + <StatusBarStyled> + <StatusBarItem> + <MdDone style={{ marginRight: '4px' }} /> placeholder + </StatusBarItem> + <InteractiveStatusBarItem>{display?.id}</InteractiveStatusBarItem> + {renderStatusBarContent(status)} + <Spacer /> + <StatusBarItem>placeholder</StatusBarItem> + </StatusBarStyled> + ); +}; diff --git a/src/client-electron/renderer/renderer.tsx b/src/client-electron/renderer/renderer.tsx index 40ceebe5..245590c9 100644 --- a/src/client-electron/renderer/renderer.tsx +++ b/src/client-electron/renderer/renderer.tsx @@ -1,4 +1,11 @@ import ReactDOM from 'react-dom'; import { App } from './app'; +import { GlobalStyles } from './styles/global'; -ReactDOM.render(<App />, document.getElementById('root')); +ReactDOM.render( + <> + <GlobalStyles /> + <App /> + </>, + document.getElementById('root') +); diff --git a/src/client-electron/renderer/styles/fonts.tsx b/src/client-electron/renderer/styles/fonts.tsx new file mode 100644 index 00000000..f473c9cf --- /dev/null +++ b/src/client-electron/renderer/styles/fonts.tsx @@ -0,0 +1,24 @@ +import RajdhaniLight from '../assets/fonts/Rajdhani/Rajdhani-Light.ttf'; +import RajdhaniRegular from '../assets/fonts/Rajdhani/Rajdhani-Regular.ttf'; +import RajdhaniMedium from '../assets/fonts/Rajdhani/Rajdhani-Medium.ttf'; +import RajdhaniSemiBold from '../assets/fonts/Rajdhani/Rajdhani-SemiBold.ttf'; +import RajdhaniBold from '../assets/fonts/Rajdhani/Rajdhani-Bold.ttf'; + +const rajdhaniFontFamily = [ + { url: RajdhaniLight, weight: 300 }, + { url: RajdhaniRegular, weight: 400 }, + { url: RajdhaniMedium, weight: 500 }, + { url: RajdhaniSemiBold, weight: 600 }, + { url: RajdhaniBold, weight: 700 }, +]; + +export const fonts = rajdhaniFontFamily.map( + ({ url, weight }) => ` + @font-face { + font-family: Rajdhani; + src: url(${url}); + font-weight: ${weight}; + font-style: normal; + } + ` +); diff --git a/src/client-electron/renderer/styles/global.tsx b/src/client-electron/renderer/styles/global.tsx new file mode 100644 index 00000000..d5d31df0 --- /dev/null +++ b/src/client-electron/renderer/styles/global.tsx @@ -0,0 +1,29 @@ +import { createGlobalStyle } from 'styled-components'; +import { fonts } from './fonts'; + +export const GlobalStyles = createGlobalStyle` + ${fonts} + + :root { + --primary: #ff5851; + --background: #121018; + --accent: #5FF6FF; + } + + html, + body { + height: 100%; + font-family: Rajdhani; + } + + body { + margin: 0; + background: linear-gradient(180deg, #3a1216 0%, var(--background) 82%); + } + + #root { + display: flex; + flex-direction: column; + height: 100%; + } +`; diff --git a/src/client-electron/worker/worker.ts b/src/client-electron/worker/worker.ts index a4f215eb..c397844d 100644 --- a/src/client-electron/worker/worker.ts +++ b/src/client-electron/worker/worker.ts @@ -3,21 +3,52 @@ import { BreachProtocolOCRFragment } from '@/core'; import { solveBreachProtocol } from '@/platform-node/solve'; import { ipcRenderer as ipc } from 'electron'; import { listDisplays } from 'screenshot-desktop'; +import { Action, Request, workerListener, WorkerStatus } from '../common'; + +function updateStatus(payload: WorkerStatus) { + dispatch({ type: 'SET_STATUS', payload }); +} + +function dispatch(action: Omit<Action, 'origin'>) { + ipc.send('state', { ...action, origin: 'worker' }); +} + +ipc.on('SET_ACTIVE_DISPLAY', (event, state) => { + screenId = state.id; +}); + +const disposeAsyncRequestListener = workerListener(handleAsyncRequest); + +async function handleAsyncRequest(req: Request) { + switch (req.type) { + default: + } +} let screenId: string = null; async function bootstrap() { + updateStatus(WorkerStatus.BOOTSTRAP); + setLang('en'); const displays = await listDisplays(); screenId = displays[0].id; + dispatch({ type: 'SET_DISPLAYS', payload: displays }); + dispatch({ type: 'SET_ACTIVE_DISPLAY', payload: displays[0] }); + await BreachProtocolOCRFragment.initScheduler(); ipc.send('worker:ready'); + updateStatus(WorkerStatus.READY); } bootstrap(); -ipc.on('worker:solve', async () => { +ipc.on('worker:solve', async (event) => { + updateStatus(WorkerStatus.WORKING); await solveBreachProtocol(screenId); + + event.sender.send('worker:solved'); + updateStatus(WorkerStatus.READY); }); diff --git a/types/fonts/index.d.ts b/types/fonts/index.d.ts new file mode 100644 index 00000000..1764f41e --- /dev/null +++ b/types/fonts/index.d.ts @@ -0,0 +1 @@ +declare module '*.ttf';