From e226c602be62bc9c775fa718bbf95abfcc91ba72 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 11 Jul 2024 22:17:37 +0900 Subject: [PATCH 0001/1013] =?UTF-8?q?init:=20webpack=20=EA=B0=9C=EB=B0=9C?= =?UTF-8?q?=ED=99=98=EA=B2=BD=20=EC=84=B8=ED=8C=85=20#2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.babelrc | 3 + frontend/.gitignore | 28 + frontend/custom.d.ts | 5 + frontend/index.html | 13 + frontend/package-lock.json | 7096 +++++++++++++++++++++++++++++ frontend/package.json | 33 + frontend/src/App.tsx | 9 + frontend/src/index.tsx | 4 + frontend/tsconfig.json | 19 + frontend/webpack.config.common.js | 52 + frontend/webpack.config.dev.js | 7 + frontend/webpack.config.prod.js | 7 + 12 files changed, 7276 insertions(+) create mode 100644 frontend/.babelrc create mode 100644 frontend/.gitignore create mode 100644 frontend/custom.d.ts create mode 100644 frontend/index.html create mode 100644 frontend/package-lock.json create mode 100644 frontend/package.json create mode 100644 frontend/src/App.tsx create mode 100644 frontend/src/index.tsx create mode 100644 frontend/tsconfig.json create mode 100644 frontend/webpack.config.common.js create mode 100644 frontend/webpack.config.dev.js create mode 100644 frontend/webpack.config.prod.js diff --git a/frontend/.babelrc b/frontend/.babelrc new file mode 100644 index 00000000..1320b9a3 --- /dev/null +++ b/frontend/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["@babel/preset-env"] +} diff --git a/frontend/.gitignore b/frontend/.gitignore new file mode 100644 index 00000000..95fbd9d2 --- /dev/null +++ b/frontend/.gitignore @@ -0,0 +1,28 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +.env +.env.development +.env.production diff --git a/frontend/custom.d.ts b/frontend/custom.d.ts new file mode 100644 index 00000000..8fb8d0f1 --- /dev/null +++ b/frontend/custom.d.ts @@ -0,0 +1,5 @@ +declare module "*.jpg"; +declare module "*.png"; +declare module "*.jpeg"; +declare module "*.gif"; +declare module "*.svg"; diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 00000000..afee72e8 --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,13 @@ + + + + + + ddangkong + + + +
+ + + diff --git a/frontend/package-lock.json b/frontend/package-lock.json new file mode 100644 index 00000000..a9d4ecf4 --- /dev/null +++ b/frontend/package-lock.json @@ -0,0 +1,7096 @@ +{ + "name": "frontend", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "frontend", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "react": "^18.3.1", + "react-dom": "^18.3.1" + }, + "devDependencies": { + "@babel/preset-env": "^7.24.7", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "babel-loader": "^9.1.3", + "file-loader": "^6.2.0", + "html-loader": "^5.0.0", + "html-webpack-plugin": "^5.6.0", + "ts-loader": "^9.5.1", + "typescript": "^5.5.3", + "webpack": "^5.92.1", + "webpack-cli": "^5.1.4", + "webpack-dev-server": "^5.0.4", + "webpack-merge": "^6.0.1" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", + "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", + "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "dev": true, + "peer": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helpers": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", + "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", + "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", + "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz", + "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.7.tgz", + "integrity": "sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", + "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", + "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.7.tgz", + "integrity": "sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-wrap-function": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", + "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", + "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz", + "integrity": "sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==", + "dev": true, + "dependencies": { + "@babel/helper-function-name": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", + "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.7.tgz", + "integrity": "sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.7.tgz", + "integrity": "sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", + "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.7.tgz", + "integrity": "sha512-utA4HuR6F4Vvcr+o4DnjL8fCOlgRFGbeeBEGNg3ZTrLFw6VWG5XmUrvcQ0FjIYMU2ST4XcR2Wsp7t9qOAPnxMg==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", + "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", + "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", + "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.7.tgz", + "integrity": "sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", + "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", + "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.7.tgz", + "integrity": "sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz", + "integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", + "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.7.tgz", + "integrity": "sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", + "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/template": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.7.tgz", + "integrity": "sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", + "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", + "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", + "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", + "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", + "dev": true, + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", + "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", + "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.7.tgz", + "integrity": "sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", + "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz", + "integrity": "sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", + "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", + "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", + "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.7.tgz", + "integrity": "sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.7.tgz", + "integrity": "sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==", + "dev": true, + "dependencies": { + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", + "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", + "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", + "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", + "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", + "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", + "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", + "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", + "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.7.tgz", + "integrity": "sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", + "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz", + "integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", + "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", + "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", + "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", + "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", + "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", + "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", + "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", + "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.7.tgz", + "integrity": "sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", + "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", + "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", + "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz", + "integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.7.tgz", + "integrity": "sha512-1YZNsc+y6cTvWlDHidMBsQZrZfEFjRIo/BZCT906PMdzOyXtSLTgqGdrpcuTDCXyd11Am5uQULtDIcCfnTc8fQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.7", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.7", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.24.7", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.24.7", + "@babel/plugin-transform-async-to-generator": "^7.24.7", + "@babel/plugin-transform-block-scoped-functions": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.24.7", + "@babel/plugin-transform-class-properties": "^7.24.7", + "@babel/plugin-transform-class-static-block": "^7.24.7", + "@babel/plugin-transform-classes": "^7.24.7", + "@babel/plugin-transform-computed-properties": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.7", + "@babel/plugin-transform-dotall-regex": "^7.24.7", + "@babel/plugin-transform-duplicate-keys": "^7.24.7", + "@babel/plugin-transform-dynamic-import": "^7.24.7", + "@babel/plugin-transform-exponentiation-operator": "^7.24.7", + "@babel/plugin-transform-export-namespace-from": "^7.24.7", + "@babel/plugin-transform-for-of": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.24.7", + "@babel/plugin-transform-json-strings": "^7.24.7", + "@babel/plugin-transform-literals": "^7.24.7", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", + "@babel/plugin-transform-member-expression-literals": "^7.24.7", + "@babel/plugin-transform-modules-amd": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.7", + "@babel/plugin-transform-modules-systemjs": "^7.24.7", + "@babel/plugin-transform-modules-umd": "^7.24.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", + "@babel/plugin-transform-new-target": "^7.24.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", + "@babel/plugin-transform-numeric-separator": "^7.24.7", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-object-super": "^7.24.7", + "@babel/plugin-transform-optional-catch-binding": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.24.7", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-property-literals": "^7.24.7", + "@babel/plugin-transform-regenerator": "^7.24.7", + "@babel/plugin-transform-reserved-words": "^7.24.7", + "@babel/plugin-transform-shorthand-properties": "^7.24.7", + "@babel/plugin-transform-spread": "^7.24.7", + "@babel/plugin-transform-sticky-regex": "^7.24.7", + "@babel/plugin-transform-template-literals": "^7.24.7", + "@babel/plugin-transform-typeof-symbol": "^7.24.7", + "@babel/plugin-transform-unicode-escapes": "^7.24.7", + "@babel/plugin-transform-unicode-property-regex": "^7.24.7", + "@babel/plugin-transform-unicode-regex": "^7.24.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.24.7", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true + }, + "node_modules/@babel/runtime": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", + "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", + "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.0.4.tgz", + "integrity": "sha512-aOcSN4MeAtFROysrbqG137b7gaDDSmVrl5mpo6sT/w+kcXpWnzhMjmY/Fh/sDx26NBxyIE7MB1seqLeCAzy9Sg==", + "dev": true, + "dependencies": { + "@jsonjoy.com/base64": "^1.1.1", + "@jsonjoy.com/util": "^1.1.2", + "hyperdyperid": "^1.2.0", + "thingies": "^1.20.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.2.0.tgz", + "integrity": "sha512-4B8B+3vFsY4eo33DMKyJPlQ3sBMpPFUZK2dr3O3rXrOGKKbYG44J0XSFkDo1VOQiri5HFEhIeVvItjR2xcazmg==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "dev": true + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dev": true, + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.56.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", + "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", + "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", + "dev": true + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "node_modules/@types/http-proxy": { + "version": "1.17.14", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", + "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.14.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", + "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", + "dev": true + }, + "node_modules/@types/qs": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "node_modules/@types/react": { + "version": "18.3.3", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", + "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "dev": true, + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", + "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/retry": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ws": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", + "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/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==", + "dev": true + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/babel-loader": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", + "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", + "dev": true, + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-loader/node_modules/ajv": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", + "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/babel-loader/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/babel-loader/node_modules/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==", + "dev": true + }, + "node_modules/babel-loader/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", + "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.1", + "core-js-compat": "^3.36.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/bonjour-service": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", + "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001640", + "electron-to-chromium": "^1.4.820", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.1.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001641", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001641.tgz", + "integrity": "sha512-Phv5thgl67bHYo1TtMY/MurjkHhV4EDaCosezRXgZ8jzA/Ub+wjxAvbGvjoFENStinwi5kCyOYV3mi5tOGykwA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/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, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clean-css": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", + "dev": true, + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "peer": true + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/core-js-compat": { + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", + "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", + "dev": true, + "dependencies": { + "browserslist": "^4.23.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dev": true, + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dev": true, + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.4.825", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.825.tgz", + "integrity": "sha512-OCcF+LwdgFGcsYPYC5keEEFC2XT0gBhrYbeGzHCx7i9qRFbzO/AqTmc/C/1xNhJj+JA7rzlN7mpBuStshh96Cg==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", + "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/envinfo": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", + "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", + "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/express": { + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "dev": true, + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "dev": true, + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-dir/node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-dir/node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-dir/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-dir/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-dir/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/find-cache-dir/node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "dev": true, + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/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, + "engines": { + "node": ">=4" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "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/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "node_modules/html-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/html-loader/-/html-loader-5.0.0.tgz", + "integrity": "sha512-puaGKdjdVVIFRtgIC2n5dt5bt0N5j6heXlAQZ4Do1MLjHmOT1gCE1Ogg7XZNeJlnOVHHsrZKGs5dfh+XwZ3XPw==", + "dev": true, + "dependencies": { + "html-minifier-terser": "^7.2.0", + "parse5": "^7.1.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/html-minifier-terser": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", + "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", + "dev": true, + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "~5.3.2", + "commander": "^10.0.0", + "entities": "^4.4.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.15.1" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + } + }, + "node_modules/html-minifier-terser/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", + "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", + "dev": true, + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/html-webpack-plugin/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "dev": true, + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "dev": true, + "engines": { + "node": ">=10.18" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", + "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-network-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", + "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/launch-editor": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.0.tgz", + "integrity": "sha512-vJranOAJrI/llyWGRQqiDM+adrw+k83fvmmx3+nV47g3+36xM15jE+zyZ6Ffel02+xSvuM0b2GDRosXZkbb6wA==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "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/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.9.3.tgz", + "integrity": "sha512-bsYSSnirtYTWi1+OPMFb0M048evMKyUYe0EbtuGQgq6BVQM1g1W8/KIUJCCvjgI/El0j6Q4WsmMiBwLUBSw8LA==", + "dev": true, + "dependencies": { + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.1.2", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">= 4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/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 + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dev": true, + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true, + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "dev": true, + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-retry": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.0.tgz", + "integrity": "sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA==", + "dev": true, + "dependencies": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dev": true, + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "dev": true, + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/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==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/rimraf": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.9.tgz", + "integrity": "sha512-3i7b8OcswU6CpU8Ej89quJD4O98id7TtVM5U4Mybh84zQXdrFmDLouWBEEaD/QfO3gDDfH+AGFCGsR7kngzQnA==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "14 >=14.20 || 16 >=16.20 || >=18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "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/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.31.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.2.tgz", + "integrity": "sha512-LGyRZVFm/QElZHy/CPr/O4eNZOZIzsrQ92y4v9UJe/pFJjypje2yI3C2FmPtvUEnhadlSbmG2nXtdcjHOjCfxw==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/thingies": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", + "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", + "dev": true, + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tree-dump": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", + "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/ts-loader": { + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", + "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, + "node_modules/ts-loader/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/ts-loader/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/ts-loader/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/ts-loader/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/ts-loader/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-loader/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/ts-loader/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/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/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, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/watchpack": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/webpack": { + "version": "5.92.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz", + "integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/webpack-cli/node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.2.1.tgz", + "integrity": "sha512-hRLz+jPQXo999Nx9fXVdKlg/aehsw1ajA9skAneGmT03xwmyuhvF93p6HUKKbWhXdcERtGTzUCtIQr+2IQegrA==", + "dev": true, + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^4.6.0", + "mime-types": "^2.1.31", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware/node_modules/ajv": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", + "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-middleware/node_modules/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==", + "dev": true + }, + "node_modules/webpack-dev-middleware/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-dev-server": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.0.4.tgz", + "integrity": "sha512-dljXhUgx3HqKP2d8J/fUMvhxGhzjeNVarDLcbO/EWMSgRizDkxHQDZQaLFL5VJY9tRBj2Gz+rvCEYYvhbqPHNA==", + "dev": true, + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.4.0", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "rimraf": "^5.0.5", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.1.0", + "ws": "^8.16.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ajv": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", + "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack-dev-server/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-server/node_modules/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==", + "dev": true + }, + "node_modules/webpack-dev-server/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-merge": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/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/wrap-ansi-cjs/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/wrap-ansi-cjs/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/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "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/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 00000000..ffe00a6d --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,33 @@ +{ + "name": "ddangkong-frontend", + "version": "1.0.0", + "description": "ddangkong-frontend repository", + "main": "index.js", + "scripts": { + "start": "webpack serve --config webpack.config.dev.js", + "build-dev": "webpack --config webpack.config.dev.js", + "build-prod": "webpack --config webpack.config.prod.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "react": "^18.3.1", + "react-dom": "^18.3.1" + }, + "devDependencies": { + "@babel/preset-env": "^7.24.7", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "babel-loader": "^9.1.3", + "file-loader": "^6.2.0", + "html-loader": "^5.0.0", + "html-webpack-plugin": "^5.6.0", + "ts-loader": "^9.5.1", + "typescript": "^5.5.3", + "webpack": "^5.92.1", + "webpack-cli": "^5.1.4", + "webpack-dev-server": "^5.0.4", + "webpack-merge": "^6.0.1" + } +} diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx new file mode 100644 index 00000000..360521c5 --- /dev/null +++ b/frontend/src/App.tsx @@ -0,0 +1,9 @@ +const App = () => { + return ( +
+

ddang-kong

+
+ ); +}; + +export default App; diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx new file mode 100644 index 00000000..a6fc2ab4 --- /dev/null +++ b/frontend/src/index.tsx @@ -0,0 +1,4 @@ +import ReactDOM from "react-dom/client"; +import App from "./App"; + +ReactDOM.createRoot(document.getElementById("root")!).render(); diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json new file mode 100644 index 00000000..25c0d92b --- /dev/null +++ b/frontend/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ESNext", // 코드의 변환 대상 ECMAScript 버전을 최신 버전으로 지정 + "module": "ESNext", // 최신 ECMAScript 버전 모듈 시스템을 타겟으로 컴파일 + "moduleResolution": "node", // TypeScript가 모듈을 해석하고 처리하는 방식 지정 + "outDir": "./dist", // 컴파일된 파일이 저장될 출력 디렉토리 지정 + "noImplicitAny": true, // 암시적 any를 허용하지 않음 + "strict": true, // 엄격한 타입 검사 + "jsx": "react-jsx", // React 프로젝트에서 JSX를 사용하기 위해 필요 + "allowSyntheticDefaultImports": true, // default export 가 없어도 import 허용 + "sourceMap": true, // 디버깅 시 어떤 파일에서 에러났는지 추적 용이 + "baseUrl": ".", // 모듈 해석 기본 경로 + "paths": { + // 경로 별칭 설정 + "@/*": ["src/*"] + } + }, + "include": ["src"] +} diff --git a/frontend/webpack.config.common.js b/frontend/webpack.config.common.js new file mode 100644 index 00000000..ff55a214 --- /dev/null +++ b/frontend/webpack.config.common.js @@ -0,0 +1,52 @@ +const path = require("path"); +const HTMLWebpackPlugin = require("html-webpack-plugin"); + +module.exports = { + entry: "./src/index.tsx", + output: { + filename: "bundle.js", + path: path.resolve(__dirname + "/dist"), + }, + resolve: { + extensions: [".js", ".jsx", ".ts", ".tsx"], + }, + module: { + rules: [ + { + test: /\.(js|jsx)$/, + exclude: /node_modules/, + use: ["babel-loader"], + }, + { + test: /\.html$/, + use: [ + { + loader: "html-loader", + }, + ], + }, + { + test: /\.(ts|tsx)$/, + use: "ts-loader", + exclude: /node_modules/, + }, + { + test: /\.(png|jpe?g|gif|svg)$/i, + use: [ + { + loader: "file-loader", + options: { + name: "[path][name].[ext]", + }, + }, + ], + }, + ], + }, + plugins: [ + new HTMLWebpackPlugin({ + template: "./index.html", // 읽을 파일명 + filename: "./index.html", // output으로 출력할 파일명 + }), + ], +}; diff --git a/frontend/webpack.config.dev.js b/frontend/webpack.config.dev.js new file mode 100644 index 00000000..e66a1e09 --- /dev/null +++ b/frontend/webpack.config.dev.js @@ -0,0 +1,7 @@ +const { merge } = require("webpack-merge"); +const common = require("./webpack.config.common.js"); + +module.exports = merge(common, { + mode: "development", + devtool: "inline-source-map", +}); diff --git a/frontend/webpack.config.prod.js b/frontend/webpack.config.prod.js new file mode 100644 index 00000000..a2d53ae9 --- /dev/null +++ b/frontend/webpack.config.prod.js @@ -0,0 +1,7 @@ +const { merge } = require("webpack-merge"); +const common = require("./webpack.config.common.js"); + +module.exports = merge(common, { + mode: "production", + devtool: "source-map", +}); From 31c6a96a3989948719cdd631387668adc21d7f88 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Fri, 12 Jul 2024 01:52:54 +0900 Subject: [PATCH 0002/1013] =?UTF-8?q?chore:=20webpack=20=EB=B9=8C=EB=93=9C?= =?UTF-8?q?=20=EA=B2=B0=EA=B3=BC=EB=AC=BC=20=EC=A0=95=EB=A6=AC=20=EB=B0=8F?= =?UTF-8?q?=20=EC=A0=88=EB=8C=80=EA=B2=BD=EB=A1=9C=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?#2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/webpack.config.common.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/webpack.config.common.js b/frontend/webpack.config.common.js index ff55a214..a881286e 100644 --- a/frontend/webpack.config.common.js +++ b/frontend/webpack.config.common.js @@ -6,9 +6,13 @@ module.exports = { output: { filename: "bundle.js", path: path.resolve(__dirname + "/dist"), + clean: true, }, resolve: { extensions: [".js", ".jsx", ".ts", ".tsx"], + alias: { + "@": path.resolve(__dirname, "./src"), + }, }, module: { rules: [ From c565993cdcb11c64a37ad8f6b30f0fd17ce0f8ec Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 11 Jul 2024 22:41:06 +0900 Subject: [PATCH 0003/1013] =?UTF-8?q?init:=20emotion=20=EC=8A=A4=ED=83=80?= =?UTF-8?q?=EC=9D=BC=EB=A7=81=20=EB=9D=BC=EC=9D=B4=EB=B8=8C=EB=9F=AC?= =?UTF-8?q?=EB=A6=AC=20=EC=84=B8=ED=8C=85=20#2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/package-lock.json | 340 ++++++++++++++++++++++++++++----- frontend/package.json | 1 + frontend/tsconfig.json | 1 + frontend/webpack.config.dev.js | 3 + 4 files changed, 293 insertions(+), 52 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index a9d4ecf4..b9330202 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,14 +1,15 @@ { - "name": "frontend", + "name": "ddangkong-frontend", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "frontend", + "name": "ddangkong-frontend", "version": "1.0.0", "license": "ISC", "dependencies": { + "@emotion/react": "^11.11.4", "react": "^18.3.1", "react-dom": "^18.3.1" }, @@ -46,7 +47,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dev": true, "dependencies": { "@babel/highlight": "^7.24.7", "picocolors": "^1.0.0" @@ -99,7 +99,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", - "dev": true, "dependencies": { "@babel/types": "^7.24.7", "@jridgewell/gen-mapping": "^0.3.5", @@ -211,7 +210,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "dev": true, "dependencies": { "@babel/types": "^7.24.7" }, @@ -223,7 +221,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "dev": true, "dependencies": { "@babel/template": "^7.24.7", "@babel/types": "^7.24.7" @@ -236,7 +233,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "dev": true, "dependencies": { "@babel/types": "^7.24.7" }, @@ -261,7 +257,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", - "dev": true, "dependencies": { "@babel/traverse": "^7.24.7", "@babel/types": "^7.24.7" @@ -374,7 +369,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dev": true, "dependencies": { "@babel/types": "^7.24.7" }, @@ -386,7 +380,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -395,7 +388,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -442,7 +434,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", @@ -457,7 +448,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", - "dev": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -1666,7 +1656,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", - "dev": true, "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -1678,7 +1667,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.24.7", "@babel/parser": "^7.24.7", @@ -1692,7 +1680,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.24.7", "@babel/generator": "^7.24.7", @@ -1713,7 +1700,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", - "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.24.7", "@babel/helper-validator-identifier": "^7.24.7", @@ -1732,6 +1718,133 @@ "node": ">=10.0.0" } }, + "node_modules/@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "dependencies": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/@emotion/react": { + "version": "11.11.4", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", + "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.4.tgz", + "integrity": "sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ==", + "dependencies": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -1780,7 +1893,6 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -1794,7 +1906,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -1803,7 +1914,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -1821,14 +1931,12 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -2043,6 +2151,11 @@ "@types/node": "*" } }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, "node_modules/@types/prop-types": { "version": "15.7.12", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", @@ -2459,7 +2572,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, "dependencies": { "color-convert": "^1.9.0" }, @@ -2556,6 +2668,20 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, "node_modules/babel-plugin-polyfill-corejs2": { "version": "0.4.11", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", @@ -2794,6 +2920,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, "node_modules/camel-case": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", @@ -2828,7 +2962,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, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -2842,7 +2975,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, "engines": { "node": ">=4" } @@ -2851,7 +2983,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -2922,7 +3053,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, "dependencies": { "color-name": "1.1.3" } @@ -2930,8 +3060,7 @@ "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/colorette": { "version": "2.0.20", @@ -3073,6 +3202,21 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3118,14 +3262,12 @@ "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/debug": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -3406,6 +3548,14 @@ "node": ">=4" } }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, "node_modules/es-define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", @@ -3452,7 +3602,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, "engines": { "node": ">=0.8.0" } @@ -3812,6 +3961,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -3918,7 +4072,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4006,7 +4159,6 @@ "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, "engines": { "node": ">=4" } @@ -4084,7 +4236,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -4101,6 +4252,14 @@ "he": "bin/he" } }, + "node_modules/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==", + "dependencies": { + "react-is": "^16.7.0" + } + }, "node_modules/hpack.js": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", @@ -4395,6 +4554,29 @@ "node": ">=0.10.0" } }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } + }, "node_modules/import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -4438,6 +4620,11 @@ "node": ">= 10" } }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -4454,7 +4641,6 @@ "version": "2.14.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", - "dev": true, "dependencies": { "hasown": "^2.0.2" }, @@ -4659,7 +4845,6 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, "bin": { "jsesc": "bin/jsesc" }, @@ -4670,8 +4855,7 @@ "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "node_modules/json-schema-traverse": { "version": "0.4.1", @@ -4710,6 +4894,11 @@ "shell-quote": "^1.8.1" } }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -4923,8 +5112,7 @@ "node_modules/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==" }, "node_modules/multicast-dns": { "version": "7.2.5", @@ -5153,6 +5341,34 @@ "tslib": "^2.0.3" } }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parse5": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", @@ -5205,8 +5421,7 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-scurry": { "version": "1.11.1", @@ -5236,11 +5451,18 @@ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", "dev": true }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, "node_modules/picocolors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -5393,6 +5615,11 @@ "react": "^18.3.1" } }, + "node_modules/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==" + }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -5452,8 +5679,7 @@ "node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "node_modules/regenerator-transform": { "version": "0.15.2", @@ -5543,7 +5769,6 @@ "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -6109,6 +6334,11 @@ "node": ">=6" } }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, "node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -6128,7 +6358,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -6219,7 +6448,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, "engines": { "node": ">=4" } @@ -7080,6 +7308,14 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, "node_modules/yocto-queue": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index ffe00a6d..807c33dd 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -12,6 +12,7 @@ "author": "", "license": "ISC", "dependencies": { + "@emotion/react": "^11.11.4", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index 25c0d92b..72d246b0 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -7,6 +7,7 @@ "noImplicitAny": true, // 암시적 any를 허용하지 않음 "strict": true, // 엄격한 타입 검사 "jsx": "react-jsx", // React 프로젝트에서 JSX를 사용하기 위해 필요 + "jsxImportSource": "@emotion/react", // 새로운 JSX 변환 방식(React 17+)으로 css prop 사용하기 위해 필요 "allowSyntheticDefaultImports": true, // default export 가 없어도 import 허용 "sourceMap": true, // 디버깅 시 어떤 파일에서 에러났는지 추적 용이 "baseUrl": ".", // 모듈 해석 기본 경로 diff --git a/frontend/webpack.config.dev.js b/frontend/webpack.config.dev.js index e66a1e09..b1bd6a42 100644 --- a/frontend/webpack.config.dev.js +++ b/frontend/webpack.config.dev.js @@ -4,4 +4,7 @@ const common = require("./webpack.config.common.js"); module.exports = merge(common, { mode: "development", devtool: "inline-source-map", + devServer: { + port: 3000, + }, }); From 8cd993acf4c30fdded2c445e67b27f3cf11fe78f Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sat, 13 Jul 2024 16:26:14 +0900 Subject: [PATCH 0004/1013] =?UTF-8?q?init:=20babel=20=EC=84=B8=ED=8C=85=20?= =?UTF-8?q?#2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.babelrc | 14 +- frontend/package-lock.json | 550 ++++++++++++++++++++++++++++++------- frontend/package.json | 7 +- 3 files changed, 466 insertions(+), 105 deletions(-) diff --git a/frontend/.babelrc b/frontend/.babelrc index 1320b9a3..ed266ad8 100644 --- a/frontend/.babelrc +++ b/frontend/.babelrc @@ -1,3 +1,15 @@ { - "presets": ["@babel/preset-env"] + "presets": [ + [ + "@babel/preset-env", + { + "targets": "> 2%, not dead", + "useBuiltIns": "usage", + "corejs": "3.37", + "shippedProposals": true + } + ], + "@babel/preset-typescript", + ["@babel/preset-react", { "runtime": "automatic" }] + ] } diff --git a/frontend/package-lock.json b/frontend/package-lock.json index b9330202..413c7633 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -14,10 +14,15 @@ "react-dom": "^18.3.1" }, "devDependencies": { - "@babel/preset-env": "^7.24.7", + "@babel/cli": "^7.24.8", + "@babel/core": "^7.24.8", + "@babel/preset-env": "^7.24.8", + "@babel/preset-react": "^7.24.7", + "@babel/preset-typescript": "^7.24.7", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "babel-loader": "^9.1.3", + "core-js": "^3.37.1", "file-loader": "^6.2.0", "html-loader": "^5.0.0", "html-webpack-plugin": "^5.6.0", @@ -34,7 +39,6 @@ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, - "peer": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -43,6 +47,87 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/cli": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.24.8.tgz", + "integrity": "sha512-isdp+G6DpRyKc+3Gqxy2rjzgF7Zj9K0mzLNnxz+E/fgeag8qT3vVulX4gY9dGO1q0y+0lUv6V3a+uhUzMzrwXg==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "commander": "^6.2.0", + "convert-source-map": "^2.0.0", + "fs-readdir-recursive": "^1.1.0", + "glob": "^7.2.0", + "make-dir": "^2.1.0", + "slash": "^2.0.0" + }, + "bin": { + "babel": "bin/babel.js", + "babel-external-helpers": "bin/babel-external-helpers.js" + }, + "engines": { + "node": ">=6.9.0" + }, + "optionalDependencies": { + "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3", + "chokidar": "^3.4.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/cli/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@babel/cli/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@babel/cli/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@babel/cli/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@babel/code-frame": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", @@ -56,31 +141,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", - "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.8.tgz", + "integrity": "sha512-c4IM7OTg6k1Q+AJ153e2mc2QVTezTwnb4VzquwcyiEzGnW0Kedv4do/TrkU98qPeC5LNiMt/QXwIjzYXLBpyZg==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", - "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.8.tgz", + "integrity": "sha512-6AWcmZC/MZCO0yKys4uhg5NlxL0ESF3K6IAaoQ+xSXvPyPyxNWRafP+GDbI88Oh68O7QkJgmEtedWPM9U0pZNg==", "dev": true, - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helpers": "^7.24.7", - "@babel/parser": "^7.24.7", + "@babel/generator": "^7.24.8", + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-module-transforms": "^7.24.8", + "@babel/helpers": "^7.24.8", + "@babel/parser": "^7.24.8", "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.8", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -96,11 +180,11 @@ } }, "node_modules/@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.8.tgz", + "integrity": "sha512-47DG+6F5SzOi0uEvK4wMShmn5yY0mVjVJoWTphdY2B4Rx9wHgjK7Yhtr0ru6nE+sn0v38mzrWOlah0p/YlHHOQ==", "dependencies": { - "@babel/types": "^7.24.7", + "@babel/types": "^7.24.8", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -135,14 +219,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", - "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz", + "integrity": "sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.24.8", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -151,15 +235,15 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz", - "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.8.tgz", + "integrity": "sha512-4f6Oqnmyp2PP3olgUMmOwC3akxSm5aBYraQ6YDdKy7NcAMkDECHWG0DEnV6M2UAkERgIBhYt8S27rURPg7SxWA==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-function-name": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.8", "@babel/helper-optimise-call-expression": "^7.24.7", "@babel/helper-replace-supers": "^7.24.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", @@ -241,13 +325,13 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", - "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", + "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", "dev": true, "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -266,9 +350,9 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", - "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.8.tgz", + "integrity": "sha512-m4vWKVqvkVAWLXfHCCfff2luJj86U+J0/x+0N3ArG/tP0Fq7zky2dYwMbtPmkc/oulkkbjdL3uWzuoBwQ8R00Q==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.24.7", @@ -297,9 +381,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", - "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", "dev": true, "engines": { "node": ">=6.9.0" @@ -377,9 +461,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", "engines": { "node": ">=6.9.0" } @@ -393,9 +477,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", - "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", "dev": true, "engines": { "node": ">=6.9.0" @@ -417,14 +501,13 @@ } }, "node_modules/@babel/helpers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", - "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.8.tgz", + "integrity": "sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==", "dev": true, - "peer": true, "dependencies": { "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/types": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -445,9 +528,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", + "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", "bin": { "parser": "bin/babel-parser.js" }, @@ -648,6 +731,21 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", @@ -750,6 +848,21 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", + "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-unicode-sets-regex": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", @@ -880,16 +993,16 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.7.tgz", - "integrity": "sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.8.tgz", + "integrity": "sha512-VXy91c47uujj758ud9wx+OMgheXm4qJfyhj1P18YvlrQkNOSrwsteHk+EFS3OMGfhMhpZa0A+81eE7G4QC+3CA==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.8", "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.8", "@babel/helper-replace-supers": "^7.24.7", "@babel/helper-split-export-declaration": "^7.24.7", "globals": "^11.1.0" @@ -918,12 +1031,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.7.tgz", - "integrity": "sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz", + "integrity": "sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1123,13 +1236,13 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.7.tgz", - "integrity": "sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz", + "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", "@babel/helper-simple-access": "^7.24.7" }, "engines": { @@ -1287,12 +1400,12 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.7.tgz", - "integrity": "sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz", + "integrity": "sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.8", "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, @@ -1367,6 +1480,71 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.7.tgz", + "integrity": "sha512-H/Snz9PFxKsS1JLI4dJLtnJgCJRoo0AUm3chP6NYr+9En1JMKloheEiLIhlp5MDVznWo+H3AAC1Mc8lmUEpsgg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.24.7.tgz", + "integrity": "sha512-+Dj06GDZEFRYvclU6k4bme55GKBEWUmByM/eoKuqg4zTNQHiApWRhQph5fxQB2wAEFvRzL1tOEj1RJ19wJrhoA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-jsx": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.24.7.tgz", + "integrity": "sha512-QG9EnzoGn+Qar7rxuW+ZOsbWOt56FvvI93xInqsZDC5fsekx1AlIO4KIJ5M+D0p0SqSH156EpmZyXq630B8OlQ==", + "dev": true, + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.7.tgz", + "integrity": "sha512-PLgBVk3fzbmEjBJ/u8kFzOqS9tUeDjiaWud/rRym/yjCo/M9cASPlnrd2ZmmZpQT40fOOrvR8jh+n8jikrOhNA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-regenerator": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", @@ -1460,12 +1638,30 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.7.tgz", - "integrity": "sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz", + "integrity": "sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.8.tgz", + "integrity": "sha512-CgFgtN61BbdOGCP4fLaAMOPkzWUh6yQZNMr5YSt8uz2cZSSiQONCQFWqsE4NeVfOIhqDOlS9CR3WD91FzMeB2Q==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/plugin-syntax-typescript": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1538,15 +1734,15 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.7.tgz", - "integrity": "sha512-1YZNsc+y6cTvWlDHidMBsQZrZfEFjRIo/BZCT906PMdzOyXtSLTgqGdrpcuTDCXyd11Am5uQULtDIcCfnTc8fQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.8.tgz", + "integrity": "sha512-vObvMZB6hNWuDxhSaEPTKCwcqkAIuDtE+bQGn4XMXne1DSLzFVY8Vmj1bm+mUQXYNN8NmaQEO+r8MMbzPr1jBQ==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", + "@babel/compat-data": "^7.24.8", + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-option": "^7.24.8", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.7", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.7", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", @@ -1577,9 +1773,9 @@ "@babel/plugin-transform-block-scoping": "^7.24.7", "@babel/plugin-transform-class-properties": "^7.24.7", "@babel/plugin-transform-class-static-block": "^7.24.7", - "@babel/plugin-transform-classes": "^7.24.7", + "@babel/plugin-transform-classes": "^7.24.8", "@babel/plugin-transform-computed-properties": "^7.24.7", - "@babel/plugin-transform-destructuring": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.8", "@babel/plugin-transform-dotall-regex": "^7.24.7", "@babel/plugin-transform-duplicate-keys": "^7.24.7", "@babel/plugin-transform-dynamic-import": "^7.24.7", @@ -1592,7 +1788,7 @@ "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", "@babel/plugin-transform-member-expression-literals": "^7.24.7", "@babel/plugin-transform-modules-amd": "^7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.8", "@babel/plugin-transform-modules-systemjs": "^7.24.7", "@babel/plugin-transform-modules-umd": "^7.24.7", "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", @@ -1602,7 +1798,7 @@ "@babel/plugin-transform-object-rest-spread": "^7.24.7", "@babel/plugin-transform-object-super": "^7.24.7", "@babel/plugin-transform-optional-catch-binding": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.8", "@babel/plugin-transform-parameters": "^7.24.7", "@babel/plugin-transform-private-methods": "^7.24.7", "@babel/plugin-transform-private-property-in-object": "^7.24.7", @@ -1613,7 +1809,7 @@ "@babel/plugin-transform-spread": "^7.24.7", "@babel/plugin-transform-sticky-regex": "^7.24.7", "@babel/plugin-transform-template-literals": "^7.24.7", - "@babel/plugin-transform-typeof-symbol": "^7.24.7", + "@babel/plugin-transform-typeof-symbol": "^7.24.8", "@babel/plugin-transform-unicode-escapes": "^7.24.7", "@babel/plugin-transform-unicode-property-regex": "^7.24.7", "@babel/plugin-transform-unicode-regex": "^7.24.7", @@ -1622,7 +1818,7 @@ "babel-plugin-polyfill-corejs2": "^0.4.10", "babel-plugin-polyfill-corejs3": "^0.10.4", "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.31.0", + "core-js-compat": "^3.37.1", "semver": "^6.3.1" }, "engines": { @@ -1646,6 +1842,45 @@ "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, + "node_modules/@babel/preset-react": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.7.tgz", + "integrity": "sha512-AAH4lEkpmzFWrGVlHaxJB7RLH21uPQ9+He+eFLWHmF9IuFQVugz8eAsamaW0DXRrTfco5zj1wWtpdcXJUOfsag==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-transform-react-display-name": "^7.24.7", + "@babel/plugin-transform-react-jsx": "^7.24.7", + "@babel/plugin-transform-react-jsx-development": "^7.24.7", + "@babel/plugin-transform-react-pure-annotations": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz", + "integrity": "sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-syntax-jsx": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.7", + "@babel/plugin-transform-typescript": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/regjsgen": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", @@ -1677,18 +1912,18 @@ } }, "node_modules/@babel/traverse": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", - "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz", + "integrity": "sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==", "dependencies": { "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", + "@babel/generator": "^7.24.8", "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-function-name": "^7.24.7", "@babel/helper-hoist-variables": "^7.24.7", "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/parser": "^7.24.8", + "@babel/types": "^7.24.8", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1697,11 +1932,11 @@ } }, "node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.8.tgz", + "integrity": "sha512-SkSBEHwwJRU52QEVZBmMBnE5Ux2/6WU1grdYyOhpbCNxbmJrDuDCphBzKZSO3taf0zztp+qkWlymE5tVL5l0TA==", "dependencies": { - "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, @@ -2002,6 +2237,13 @@ "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", "dev": true }, + "node_modules/@nicolo-ribaudo/chokidar-2": { + "version": "2.1.8-no-fsevents.3", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz", + "integrity": "sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==", + "dev": true, + "optional": true + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -3131,6 +3373,12 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, "node_modules/connect-history-api-fallback": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", @@ -3165,8 +3413,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/cookie": { "version": "0.6.0", @@ -3183,6 +3430,17 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "dev": true }, + "node_modules/core-js": { + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz", + "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, "node_modules/core-js-compat": { "version": "3.37.1", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", @@ -4054,6 +4312,18 @@ "node": ">= 0.6" } }, + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -4081,7 +4351,6 @@ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, - "peer": true, "engines": { "node": ">=6.9.0" } @@ -4596,6 +4865,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -4975,6 +5255,28 @@ "yallist": "^3.0.2" } }, + "node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -5239,6 +5541,15 @@ "node": ">= 0.8" } }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", @@ -5409,6 +5720,15 @@ "node": ">=8" } }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -5476,6 +5796,15 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -6157,6 +6486,15 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -7281,6 +7619,12 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, "node_modules/ws": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 807c33dd..05766bae 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,10 +17,15 @@ "react-dom": "^18.3.1" }, "devDependencies": { - "@babel/preset-env": "^7.24.7", + "@babel/cli": "^7.24.8", + "@babel/core": "^7.24.8", + "@babel/preset-env": "^7.24.8", + "@babel/preset-react": "^7.24.7", + "@babel/preset-typescript": "^7.24.7", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "babel-loader": "^9.1.3", + "core-js": "^3.37.1", "file-loader": "^6.2.0", "html-loader": "^5.0.0", "html-webpack-plugin": "^5.6.0", From b3570b5b09e0a219df7e47d47bff3ec340a8750a Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sat, 13 Jul 2024 16:26:55 +0900 Subject: [PATCH 0005/1013] =?UTF-8?q?chore:=20=EA=B0=9C=EB=B0=9C=ED=99=98?= =?UTF-8?q?=EA=B2=BD=EC=97=90=EC=84=9C=20ts-loader,=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=EB=8D=95=EC=85=98=ED=99=98=EA=B2=BD=EC=97=90=EC=84=9C=20babel-?= =?UTF-8?q?loader=20=EC=A0=81=EC=9A=A9=20#2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/package-lock.json | 236 ++++++++++++++++++++++++++++++ frontend/package.json | 1 + frontend/webpack.config.common.js | 10 -- frontend/webpack.config.dev.js | 13 ++ frontend/webpack.config.prod.js | 9 ++ 5 files changed, 259 insertions(+), 10 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 413c7633..fe65231c 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -24,6 +24,7 @@ "babel-loader": "^9.1.3", "core-js": "^3.37.1", "file-loader": "^6.2.0", + "fork-ts-checker-webpack-plugin": "^9.0.2", "html-loader": "^5.0.0", "html-webpack-plugin": "^5.6.0", "ts-loader": "^9.5.1", @@ -2834,6 +2835,12 @@ "node": ">= 8" } }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -3538,6 +3545,15 @@ } } }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/default-browser": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", @@ -4294,6 +4310,167 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-9.0.2.tgz", + "integrity": "sha512-Uochze2R8peoN1XqlSi/rGUkDQpRogtLFocP9+PGu68zk1BDAKXfdeCdyVZpgTk8V8WFVQXdEz426VKjXLO1Gg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "cosmiconfig": "^8.2.0", + "deepmerge": "^4.2.2", + "fs-extra": "^10.0.0", + "memfs": "^3.4.1", + "minimatch": "^3.0.4", + "node-abort-controller": "^3.0.1", + "schema-utils": "^3.1.1", + "semver": "^7.3.5", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">=12.13.0", + "yarn": ">=1.0.0" + }, + "peerDependencies": { + "typescript": ">3.6.0", + "webpack": "^5.11.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/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/fork-ts-checker-webpack-plugin/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/fork-ts-checker-webpack-plugin/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/fork-ts-checker-webpack-plugin/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/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dev": true, + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/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/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -4312,6 +4489,26 @@ "node": ">= 0.6" } }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs-monkey": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", + "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==", + "dev": true + }, "node_modules/fs-readdir-recursive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", @@ -5121,6 +5318,18 @@ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -5155,6 +5364,18 @@ "node": ">=6" } }, + "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/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -5454,6 +5675,12 @@ "tslib": "^2.0.3" } }, + "node_modules/node-abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", + "dev": true + }, "node_modules/node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", @@ -7007,6 +7234,15 @@ "node": ">=4" } }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 05766bae..74117120 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -27,6 +27,7 @@ "babel-loader": "^9.1.3", "core-js": "^3.37.1", "file-loader": "^6.2.0", + "fork-ts-checker-webpack-plugin": "^9.0.2", "html-loader": "^5.0.0", "html-webpack-plugin": "^5.6.0", "ts-loader": "^9.5.1", diff --git a/frontend/webpack.config.common.js b/frontend/webpack.config.common.js index a881286e..061a0856 100644 --- a/frontend/webpack.config.common.js +++ b/frontend/webpack.config.common.js @@ -16,11 +16,6 @@ module.exports = { }, module: { rules: [ - { - test: /\.(js|jsx)$/, - exclude: /node_modules/, - use: ["babel-loader"], - }, { test: /\.html$/, use: [ @@ -29,11 +24,6 @@ module.exports = { }, ], }, - { - test: /\.(ts|tsx)$/, - use: "ts-loader", - exclude: /node_modules/, - }, { test: /\.(png|jpe?g|gif|svg)$/i, use: [ diff --git a/frontend/webpack.config.dev.js b/frontend/webpack.config.dev.js index b1bd6a42..82f39c17 100644 --- a/frontend/webpack.config.dev.js +++ b/frontend/webpack.config.dev.js @@ -1,5 +1,6 @@ const { merge } = require("webpack-merge"); const common = require("./webpack.config.common.js"); +const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin"); module.exports = merge(common, { mode: "development", @@ -7,4 +8,16 @@ module.exports = merge(common, { devServer: { port: 3000, }, + module: { + rules: [ + { + test: /\.(ts|tsx)$/, + use: "ts-loader", + exclude: /node_modules/, + }, + ] + }, + plugins: [ + new ForkTsCheckerWebpackPlugin() + ] }); diff --git a/frontend/webpack.config.prod.js b/frontend/webpack.config.prod.js index a2d53ae9..25d94c2d 100644 --- a/frontend/webpack.config.prod.js +++ b/frontend/webpack.config.prod.js @@ -4,4 +4,13 @@ const common = require("./webpack.config.common.js"); module.exports = merge(common, { mode: "production", devtool: "source-map", + module: { + rules: [ + { + test: /\.(js|jsx|ts|tsx)$/, + exclude: /node_modules/, + use: ["babel-loader"], + }, + ] + } }); From 8c9ec6b401e4eb3fac3ad0309e788a16740f75c5 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sat, 13 Jul 2024 16:49:08 +0900 Subject: [PATCH 0006/1013] =?UTF-8?q?init:=20prettier=20=EC=84=B8=ED=8C=85?= =?UTF-8?q?=20#2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.prettierrc | 11 +++++++++++ frontend/custom.d.ts | 10 +++++----- frontend/index.html | 14 ++++++-------- frontend/package-lock.json | 16 ++++++++++++++++ frontend/package.json | 1 + frontend/src/index.tsx | 6 +++--- frontend/webpack.config.common.js | 24 ++++++++++++------------ frontend/webpack.config.dev.js | 18 ++++++++---------- frontend/webpack.config.prod.js | 14 +++++++------- 9 files changed, 69 insertions(+), 45 deletions(-) create mode 100644 frontend/.prettierrc diff --git a/frontend/.prettierrc b/frontend/.prettierrc new file mode 100644 index 00000000..e30f4346 --- /dev/null +++ b/frontend/.prettierrc @@ -0,0 +1,11 @@ +{ + "printWidth": 100, + "tabWidth": 2, + "singleQuote": true, + "semi": true, + "useTabs": false, + "trailingComma": "all", + "bracketSpacing": true, + "arrowParens": "always", + "endOfLine": "auto" +} diff --git a/frontend/custom.d.ts b/frontend/custom.d.ts index 8fb8d0f1..ccb76282 100644 --- a/frontend/custom.d.ts +++ b/frontend/custom.d.ts @@ -1,5 +1,5 @@ -declare module "*.jpg"; -declare module "*.png"; -declare module "*.jpeg"; -declare module "*.gif"; -declare module "*.svg"; +declare module '*.jpg'; +declare module '*.png'; +declare module '*.jpeg'; +declare module '*.gif'; +declare module '*.svg'; diff --git a/frontend/index.html b/frontend/index.html index afee72e8..805a6cfa 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1,13 +1,11 @@ - - - - + + + ddangkong - + - +
- - + diff --git a/frontend/package-lock.json b/frontend/package-lock.json index fe65231c..a7e04ab6 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -27,6 +27,7 @@ "fork-ts-checker-webpack-plugin": "^9.0.2", "html-loader": "^5.0.0", "html-webpack-plugin": "^5.6.0", + "prettier": "^3.3.2", "ts-loader": "^9.5.1", "typescript": "^5.5.3", "webpack": "^5.92.1", @@ -6044,6 +6045,21 @@ "node": ">=8" } }, + "node_modules/prettier": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", + "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-error": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 74117120..b49630b2 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -30,6 +30,7 @@ "fork-ts-checker-webpack-plugin": "^9.0.2", "html-loader": "^5.0.0", "html-webpack-plugin": "^5.6.0", + "prettier": "^3.3.2", "ts-loader": "^9.5.1", "typescript": "^5.5.3", "webpack": "^5.92.1", diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index a6fc2ab4..dee6b695 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -1,4 +1,4 @@ -import ReactDOM from "react-dom/client"; -import App from "./App"; +import ReactDOM from 'react-dom/client'; +import App from './App'; -ReactDOM.createRoot(document.getElementById("root")!).render(); +ReactDOM.createRoot(document.getElementById('root')!).render(); diff --git a/frontend/webpack.config.common.js b/frontend/webpack.config.common.js index 061a0856..3ac38adf 100644 --- a/frontend/webpack.config.common.js +++ b/frontend/webpack.config.common.js @@ -1,17 +1,17 @@ -const path = require("path"); -const HTMLWebpackPlugin = require("html-webpack-plugin"); +const path = require('path'); +const HTMLWebpackPlugin = require('html-webpack-plugin'); module.exports = { - entry: "./src/index.tsx", + entry: './src/index.tsx', output: { - filename: "bundle.js", - path: path.resolve(__dirname + "/dist"), + filename: 'bundle.js', + path: path.resolve(__dirname + '/dist'), clean: true, }, resolve: { - extensions: [".js", ".jsx", ".ts", ".tsx"], + extensions: ['.js', '.jsx', '.ts', '.tsx'], alias: { - "@": path.resolve(__dirname, "./src"), + '@': path.resolve(__dirname, './src'), }, }, module: { @@ -20,7 +20,7 @@ module.exports = { test: /\.html$/, use: [ { - loader: "html-loader", + loader: 'html-loader', }, ], }, @@ -28,9 +28,9 @@ module.exports = { test: /\.(png|jpe?g|gif|svg)$/i, use: [ { - loader: "file-loader", + loader: 'file-loader', options: { - name: "[path][name].[ext]", + name: '[path][name].[ext]', }, }, ], @@ -39,8 +39,8 @@ module.exports = { }, plugins: [ new HTMLWebpackPlugin({ - template: "./index.html", // 읽을 파일명 - filename: "./index.html", // output으로 출력할 파일명 + template: './index.html', // 읽을 파일명 + filename: './index.html', // output으로 출력할 파일명 }), ], }; diff --git a/frontend/webpack.config.dev.js b/frontend/webpack.config.dev.js index 82f39c17..c1835603 100644 --- a/frontend/webpack.config.dev.js +++ b/frontend/webpack.config.dev.js @@ -1,10 +1,10 @@ -const { merge } = require("webpack-merge"); -const common = require("./webpack.config.common.js"); -const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin"); +const { merge } = require('webpack-merge'); +const common = require('./webpack.config.common.js'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); module.exports = merge(common, { - mode: "development", - devtool: "inline-source-map", + mode: 'development', + devtool: 'inline-source-map', devServer: { port: 3000, }, @@ -12,12 +12,10 @@ module.exports = merge(common, { rules: [ { test: /\.(ts|tsx)$/, - use: "ts-loader", + use: 'ts-loader', exclude: /node_modules/, }, - ] + ], }, - plugins: [ - new ForkTsCheckerWebpackPlugin() - ] + plugins: [new ForkTsCheckerWebpackPlugin()], }); diff --git a/frontend/webpack.config.prod.js b/frontend/webpack.config.prod.js index 25d94c2d..73665a93 100644 --- a/frontend/webpack.config.prod.js +++ b/frontend/webpack.config.prod.js @@ -1,16 +1,16 @@ -const { merge } = require("webpack-merge"); -const common = require("./webpack.config.common.js"); +const { merge } = require('webpack-merge'); +const common = require('./webpack.config.common.js'); module.exports = merge(common, { - mode: "production", - devtool: "source-map", + mode: 'production', + devtool: 'source-map', module: { rules: [ { test: /\.(js|jsx|ts|tsx)$/, exclude: /node_modules/, - use: ["babel-loader"], + use: ['babel-loader'], }, - ] - } + ], + }, }); From 09421e872f9aeab3597aa6f66c6a325abebec1aa Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sat, 13 Jul 2024 19:06:32 +0900 Subject: [PATCH 0007/1013] =?UTF-8?q?init:=20eslint=20=EC=84=B8=ED=8C=85?= =?UTF-8?q?=20#2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.eslintrc.json | 56 + frontend/package-lock.json | 3074 +++++++++++++++++++++++++++++++++++- frontend/package.json | 12 +- frontend/src/index.tsx | 1 + 4 files changed, 3086 insertions(+), 57 deletions(-) create mode 100644 frontend/.eslintrc.json diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json new file mode 100644 index 00000000..5e8fcd5d --- /dev/null +++ b/frontend/.eslintrc.json @@ -0,0 +1,56 @@ +{ + "env": { + "browser": true, + "es2021": true + }, + "extends": [ + "eslint:recommended", + "plugin:react/recommended", + "plugin:@typescript-eslint/recommended", + "plugin:react-hooks/recommended", + "plugin:import/recommended", + "plugin:jsx-a11y/recommended", + "prettier" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": ["react", "@typescript-eslint", "react-refresh"], + "rules": { + "react/react-in-jsx-scope": "off", + "@typescript-eslint/no-unused-vars": "warn", + "react/function-component-definition": ["error", { "namedComponents": "arrow-function" }], + "react-refresh/only-export-components": ["warn", { "allowConstantExport": true }], + "import/no-unresolved": "off", + "import/order": [ + "error", + { + "groups": ["builtin", "external", ["parent", "sibling"], "index"], + "pathGroups": [ + { + "pattern": "react*", + "group": "builtin", + "position": "before" + }, + { + "pattern": "@/*", + "group": "internal", + "position": "after" + } + ], + "alphabetize": { + "order": "asc", + "caseInsensitive": true + }, + "newlines-between": "always" + } + ] + }, + "settings": { + "react": { + "version": "detect" + } + } +} diff --git a/frontend/package-lock.json b/frontend/package-lock.json index a7e04ab6..caa1e3d9 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -21,8 +21,17 @@ "@babel/preset-typescript": "^7.24.7", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", + "@typescript-eslint/eslint-plugin": "^7.16.0", + "@typescript-eslint/parser": "^7.16.0", "babel-loader": "^9.1.3", "core-js": "^3.37.1", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-jsx-a11y": "^6.9.0", + "eslint-plugin-react": "^7.34.3", + "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-react-refresh": "^0.4.8", "file-loader": "^6.2.0", "fork-ts-checker-webpack-plugin": "^9.0.2", "html-loader": "^5.0.0", @@ -2082,6 +2091,156 @@ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -2246,6 +2405,41 @@ "dev": true, "optional": true }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -2371,6 +2565,12 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", @@ -2491,6 +2691,209 @@ "@types/node": "*" } }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.0.tgz", + "integrity": "sha512-py1miT6iQpJcs1BiJjm54AMzeuMPBSPuKPlnT8HlfudbcS5rYeX5jajpLf3mrdRh9dA/Ec2FVUY0ifeVNDIhZw==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.16.0", + "@typescript-eslint/type-utils": "7.16.0", + "@typescript-eslint/utils": "7.16.0", + "@typescript-eslint/visitor-keys": "7.16.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.0.tgz", + "integrity": "sha512-ar9E+k7CU8rWi2e5ErzQiC93KKEFAXA2Kky0scAlPcxYblLt8+XZuHUZwlyfXILyQa95P6lQg+eZgh/dDs3+Vw==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "7.16.0", + "@typescript-eslint/types": "7.16.0", + "@typescript-eslint/typescript-estree": "7.16.0", + "@typescript-eslint/visitor-keys": "7.16.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.0.tgz", + "integrity": "sha512-8gVv3kW6n01Q6TrI1cmTZ9YMFi3ucDT7i7aI5lEikk2ebk1AEjrwX8MDTdaX5D7fPXMBLvnsaa0IFTAu+jcfOw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.0", + "@typescript-eslint/visitor-keys": "7.16.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.0.tgz", + "integrity": "sha512-j0fuUswUjDHfqV/UdW6mLtOQQseORqfdmoBNDFOqs9rvNVR2e+cmu6zJu/Ku4SDuqiJko6YnhwcL8x45r8Oqxg==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "7.16.0", + "@typescript-eslint/utils": "7.16.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.0.tgz", + "integrity": "sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.0.tgz", + "integrity": "sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.0", + "@typescript-eslint/visitor-keys": "7.16.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.0.tgz", + "integrity": "sha512-PqP4kP3hb4r7Jav+NiRCntlVzhxBNWq6ZQ+zQwII1y/G/1gdIPeYDCKr2+dH6049yJQsWZiHU6RlwvIFBXXGNA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.16.0", + "@typescript-eslint/types": "7.16.0", + "@typescript-eslint/typescript-estree": "7.16.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz", + "integrity": "sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/@webassemblyjs/ast": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", @@ -2727,6 +3130,15 @@ "acorn": "^8" } }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -2842,27 +3254,246 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true + "node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "dev": true, + "dependencies": { + "deep-equal": "^2.0.5" + } }, - "node_modules/babel-loader": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", - "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", "dev": true, "dependencies": { - "find-cache-dir": "^4.0.0", - "schema-utils": "^4.0.0" + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" }, "engines": { - "node": ">= 14.15.0" + "node": ">= 0.4" }, - "peerDependencies": { - "@babel/core": "^7.12.0", - "webpack": ">=5" + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.toreversed": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", + "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.9.1.tgz", + "integrity": "sha512-QbUdXJVTpvUTHU7871ppZkdOLBeGUKBQWHkHrvN2V9IQWGMt61zf3B45BtzjxEJzYuj0JBjBZP/hmYS/R9pmAw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", + "integrity": "sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==", + "dev": true, + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/babel-loader": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", + "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", + "dev": true, + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" } }, "node_modules/babel-loader/node_modules/ajv": { @@ -3530,6 +4161,63 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/debug": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", @@ -3546,6 +4234,50 @@ } } }, + "node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-equal/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", @@ -3624,6 +4356,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -3649,6 +4398,18 @@ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "dev": true }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/dns-packet": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", @@ -3661,6 +4422,18 @@ "node": ">=6" } }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", @@ -3831,6 +4604,66 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/es-define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", @@ -3852,46 +4685,771 @@ "node": ">= 0.4" } }, - "node_modules/es-module-lexer": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", - "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", - "dev": true - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", "dev": true, - "engines": { - "node": ">=6" + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/escape-html": { - "version": "1.0.3", + "node_modules/es-get-iterator/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/es-iterator-helpers": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", + "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.9.0.tgz", + "integrity": "sha512-nOFOCaJG2pYqORjK19lqPqxMO/JpvdCZdPtNdxY3kvom3jTvkAbOvQvD8wuD0G8BYR0IGAGYDlzqWJOh/ybn2g==", + "dev": true, + "dependencies": { + "aria-query": "~5.1.3", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.9.1", + "axobject-query": "~3.1.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "es-iterator-helpers": "^1.0.19", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.0" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.34.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.3.tgz", + "integrity": "sha512-aoW4MV891jkUulwDApQbPYTVZmeuSyFrudpbTAQuj5Fv8VL+o6df2xIGpw8B0hPjAaih1/Fb0om9grCdyFYemA==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.toreversed": "^1.1.2", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.19", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.hasown": "^1.1.4", + "object.values": "^1.2.0", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.11" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.8.tgz", + "integrity": "sha512-MIKAclwaDFIiYtVBLzDdm16E+Ty4GwhB6wZlCAG1R3Ur+F9Qbo6PRxpA5DK7XtDgm+WlCoAY2WxAwqhmIDHg6Q==", + "dev": true, + "peerDependencies": { + "eslint": ">=7" + } + }, + "node_modules/eslint-plugin-react/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/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/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/eslint/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/eslint/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/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, "engines": { - "node": ">=0.8.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/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/eslint/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" } }, "node_modules/esrecurse": { @@ -4043,12 +5601,34 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, "node_modules/fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", @@ -4058,6 +5638,15 @@ "node": ">= 4.9.1" } }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/faye-websocket": { "version": "0.11.4", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", @@ -4070,6 +5659,18 @@ "node": ">=0.8.0" } }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, "node_modules/file-loader": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", @@ -4263,6 +5864,85 @@ "flat": "cli.js" } }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/flat-cache/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flat-cache/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, "node_modules/follow-redirects": { "version": "1.15.6", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", @@ -4283,6 +5963,15 @@ } } }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, "node_modules/foreground-child": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", @@ -4544,6 +6233,33 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -4584,6 +6300,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -4630,6 +6363,51 @@ "node": ">=4" } }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -4648,12 +6426,27 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, "node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", "dev": true }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -4687,11 +6480,26 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, "engines": { "node": ">= 0.4" }, @@ -5021,6 +6829,15 @@ "node": ">=0.10.0" } }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -5063,6 +6880,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -5080,6 +6906,20 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/interpret": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", @@ -5098,11 +6938,70 @@ "node": ">= 10" } }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -5115,6 +7014,34 @@ "node": ">=8" } }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-core-module": { "version": "2.14.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", @@ -5129,6 +7056,36 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-docker": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", @@ -5153,6 +7110,18 @@ "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -5162,6 +7131,21 @@ "node": ">=8" } }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -5192,6 +7176,30 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-network-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", @@ -5213,6 +7221,30 @@ "node": ">=0.12.0" } }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-obj": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", @@ -5231,22 +7263,150 @@ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "dependencies": { - "isobject": "^3.0.1" + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "node_modules/is-weakset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-wsl": { @@ -5285,6 +7445,19 @@ "node": ">=0.10.0" } }, + "node_modules/iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } + }, "node_modules/jackspeak": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", @@ -5342,6 +7515,12 @@ "node": ">=4" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -5353,6 +7532,12 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -5377,6 +7562,30 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -5386,6 +7595,24 @@ "node": ">=0.10.0" } }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/launch-editor": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.0.tgz", @@ -5396,6 +7623,19 @@ "shell-quote": "^1.8.1" } }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -5448,6 +7688,12 @@ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "dev": true }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -5539,6 +7785,15 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -5624,6 +7879,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", @@ -5651,6 +7915,12 @@ "multicast-dns": "cli.js" } }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -5730,6 +8000,15 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", @@ -5742,6 +8021,129 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.hasown": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", + "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/obuf": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", @@ -5811,6 +8213,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -6045,6 +8464,24 @@ "node": ">=8" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/prettier": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", @@ -6076,6 +8513,17 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -6122,6 +8570,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -6230,6 +8698,27 @@ "node": ">= 10.13.0" } }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -6262,6 +8751,24 @@ "@babel/runtime": "^7.8.4" } }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regexpu-core": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", @@ -6383,6 +8890,16 @@ "node": ">= 4" } }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rimraf": { "version": "5.0.9", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.9.tgz", @@ -6407,12 +8924,59 @@ "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", "dev": true, "engines": { - "node": ">=18" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-array-concat/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -6433,6 +8997,23 @@ } ] }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -6657,6 +9238,21 @@ "node": ">= 0.4" } }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -6807,6 +9403,18 @@ "node": ">= 0.8" } }, + "node_modules/stop-iteration-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", + "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "dev": true, + "dependencies": { + "internal-slot": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -6881,6 +9489,91 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/string.prototype.includes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.0.tgz", + "integrity": "sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -6906,6 +9599,15 @@ "node": ">=8" } }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -6915,6 +9617,18 @@ "node": ">=6" } }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/stylis": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", @@ -7007,6 +9721,12 @@ } } }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, "node_modules/thingies": { "version": "1.21.0", "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", @@ -7070,6 +9790,18 @@ "tslib": "2" } }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, "node_modules/ts-loader": { "version": "9.5.1", "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", @@ -7172,12 +9904,60 @@ "node": ">=8" } }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, "node_modules/tslib": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", "dev": true }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -7191,6 +9971,79 @@ "node": ">= 0.6" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typescript": { "version": "5.5.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", @@ -7204,6 +10057,21 @@ "node": ">=14.17" } }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -7738,12 +10606,106 @@ "node": ">= 8" } }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", + "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "dev": true, + "dependencies": { + "function.prototype.name": "^1.1.5", + "has-tostringtag": "^1.0.0", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/wildcard": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", "dev": true }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index b49630b2..eda6b08a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -6,7 +6,8 @@ "scripts": { "start": "webpack serve --config webpack.config.dev.js", "build-dev": "webpack --config webpack.config.dev.js", - "build-prod": "webpack --config webpack.config.prod.js" + "build-prod": "webpack --config webpack.config.prod.js", + "lint": "npx eslint --ext .ts,.tsx ." }, "keywords": [], "author": "", @@ -24,8 +25,17 @@ "@babel/preset-typescript": "^7.24.7", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", + "@typescript-eslint/eslint-plugin": "^7.16.0", + "@typescript-eslint/parser": "^7.16.0", "babel-loader": "^9.1.3", "core-js": "^3.37.1", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-jsx-a11y": "^6.9.0", + "eslint-plugin-react": "^7.34.3", + "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-react-refresh": "^0.4.8", "file-loader": "^6.2.0", "fork-ts-checker-webpack-plugin": "^9.0.2", "html-loader": "^5.0.0", diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index dee6b695..0d3cae1d 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -1,4 +1,5 @@ import ReactDOM from 'react-dom/client'; + import App from './App'; ReactDOM.createRoot(document.getElementById('root')!).render(); From 89dc2e846a4109ebd89639903994c5862ff0d8fb Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sun, 14 Jul 2024 13:31:25 +0900 Subject: [PATCH 0008/1013] =?UTF-8?q?init:=20husky=EB=A1=9C=20lint=20&=20p?= =?UTF-8?q?rettier=20&=20=EC=BB=A4=EB=B0=8B=20=EC=BB=A8=EB=B2=A4=EC=85=98?= =?UTF-8?q?=20=ED=99=95=EC=9D=B8=20=EA=B8=B0=EB=8A=A5=20=EC=84=B8=ED=8C=85?= =?UTF-8?q?=20#2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.husky/commit-msg | 23 ++ frontend/.husky/pre-commit | 1 + frontend/.husky/pre-push | 1 + frontend/package-lock.json | 642 +++++++++++++++++++++++++++++++++++++ frontend/package.json | 11 +- 5 files changed, 677 insertions(+), 1 deletion(-) create mode 100644 frontend/.husky/commit-msg create mode 100644 frontend/.husky/pre-commit create mode 100644 frontend/.husky/pre-push diff --git a/frontend/.husky/commit-msg b/frontend/.husky/commit-msg new file mode 100644 index 00000000..86807a9d --- /dev/null +++ b/frontend/.husky/commit-msg @@ -0,0 +1,23 @@ +COMMIT_MSG_FILE=$1 +COMMIT_MSG=$(cat $1) + +# 허용하는 commit prefix +ALLOWED_PREFIXES="^(feat|fix|refactor|build|docs|chore|test|style|design|init): " + +# 현재 브랜치명 +CURRENT_BRANCH=$(git branch --show-current) + +# 브랜치명에서 이슈 번호 추출. 브랜치명 : {prefix}/#{issue_number} +ISSUE_NUMBER=$(echo $CURRENT_BRANCH | sed -n 's/.*#\([0-9]*\).*/\1/p') + + +if ! echo "$COMMIT_MSG" | grep -Eq "$ALLOWED_PREFIXES"; then + echo "Error: Commit message does not follow the convention." + echo "Allowed prefixes: feat:, fix:, refactor:, build:, docs:, chore:, test:, style:, design:, init:" + exit 1 +fi + +if ! echo "$COMMIT_MSG" | grep -q "#$ISSUE_NUMBER"; then + echo "Error: Commit message does not contain the issue number #$ISSUE_NUMBER." + exit 1 +fi diff --git a/frontend/.husky/pre-commit b/frontend/.husky/pre-commit new file mode 100644 index 00000000..f450749a --- /dev/null +++ b/frontend/.husky/pre-commit @@ -0,0 +1 @@ +cd frontend && npx lint-staged diff --git a/frontend/.husky/pre-push b/frontend/.husky/pre-push new file mode 100644 index 00000000..ecffe9c2 --- /dev/null +++ b/frontend/.husky/pre-push @@ -0,0 +1 @@ +cd frontend && npm run build-dev diff --git a/frontend/package-lock.json b/frontend/package-lock.json index caa1e3d9..e2cc240a 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -36,6 +36,8 @@ "fork-ts-checker-webpack-plugin": "^9.0.2", "html-loader": "^5.0.0", "html-webpack-plugin": "^5.6.0", + "husky": "^9.0.11", + "lint-staged": "^15.2.7", "prettier": "^3.3.2", "ts-loader": "^9.5.1", "typescript": "^5.5.3", @@ -3203,6 +3205,18 @@ "ajv": "^6.9.1" } }, + "node_modules/ansi-escapes": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", + "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", @@ -3916,6 +3930,87 @@ "node": ">= 10.0" } }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", @@ -6269,6 +6364,18 @@ "node": ">=6.9.0" } }, + "node_modules/get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -6808,6 +6915,21 @@ "node": ">=10.17.0" } }, + "node_modules/husky": { + "version": "9.0.11", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", + "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", + "dev": true, + "bin": { + "husky": "bin.mjs" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/hyperdyperid": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", @@ -7636,11 +7758,319 @@ "node": ">= 0.8.0" } }, + "node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, + "node_modules/lint-staged": { + "version": "15.2.7", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.7.tgz", + "integrity": "sha512-+FdVbbCZ+yoh7E/RosSdqKJyUM2OEjTciH0TFNkawKgvFp1zbGlEC39RADg+xKBG1R4mhoH2j85myBQZ5wR+lw==", + "dev": true, + "dependencies": { + "chalk": "~5.3.0", + "commander": "~12.1.0", + "debug": "~4.3.4", + "execa": "~8.0.1", + "lilconfig": "~3.1.1", + "listr2": "~8.2.1", + "micromatch": "~4.0.7", + "pidtree": "~0.6.0", + "string-argv": "~0.3.2", + "yaml": "~2.4.2" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": ">=18.12.0" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/lint-staged/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/lint-staged/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/lint-staged/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/lint-staged/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/yaml": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", + "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", + "dev": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/listr2": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.3.tgz", + "integrity": "sha512-Lllokma2mtoniUOS94CcOErHWAug5iu7HOmDrvWgpw8jyQH2fomgB+7lZS4HWZxytUuQwkGOwe49FvwVaA85Xw==", + "dev": true, + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.0.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -7694,6 +8124,135 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/log-update": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", + "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", + "dev": true, + "dependencies": { + "ansi-escapes": "^6.2.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^7.0.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -8443,6 +9002,18 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", @@ -8881,6 +9452,22 @@ "node": ">=8" } }, + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", @@ -8900,6 +9487,12 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true + }, "node_modules/rimraf": { "version": "5.0.9", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.9.tgz", @@ -9334,6 +9927,46 @@ "node": ">=6" } }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -9424,6 +10057,15 @@ "safe-buffer": "~5.2.0" } }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", diff --git a/frontend/package.json b/frontend/package.json index eda6b08a..7a9c58cb 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -7,7 +7,8 @@ "start": "webpack serve --config webpack.config.dev.js", "build-dev": "webpack --config webpack.config.dev.js", "build-prod": "webpack --config webpack.config.prod.js", - "lint": "npx eslint --ext .ts,.tsx ." + "lint": "npx eslint --ext .ts,.tsx .", + "prepare": "cd .. && husky frontend/.husky" }, "keywords": [], "author": "", @@ -40,6 +41,8 @@ "fork-ts-checker-webpack-plugin": "^9.0.2", "html-loader": "^5.0.0", "html-webpack-plugin": "^5.6.0", + "husky": "^9.0.11", + "lint-staged": "^15.2.7", "prettier": "^3.3.2", "ts-loader": "^9.5.1", "typescript": "^5.5.3", @@ -47,5 +50,11 @@ "webpack-cli": "^5.1.4", "webpack-dev-server": "^5.0.4", "webpack-merge": "^6.0.1" + }, + "lint-staged": { + "**/*.{ts,tsx}": [ + "eslint --fix", + "prettier --write" + ] } } From b2188b1947cbd549f66a8b0442d7b73f0b1ac3a5 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sun, 14 Jul 2024 15:06:01 +0900 Subject: [PATCH 0009/1013] =?UTF-8?q?build:=20tastack-query,=20jest,=20RTL?= =?UTF-8?q?,=20msw,=20storybook,=20react-router-dom=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=EC=84=B1=20=EC=84=A4=EC=B9=98=20#2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/package-lock.json | 18448 +++++++++++++++++++++++++---------- frontend/package.json | 29 +- 2 files changed, 13514 insertions(+), 4963 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index e2cc240a..a24ac0bd 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -10,8 +10,10 @@ "license": "ISC", "dependencies": { "@emotion/react": "^11.11.4", + "@tanstack/react-query": "^5.51.1", "react": "^18.3.1", - "react-dom": "^18.3.1" + "react-dom": "^18.3.1", + "react-router-dom": "^6.24.1" }, "devDependencies": { "@babel/cli": "^7.24.8", @@ -19,6 +21,21 @@ "@babel/preset-env": "^7.24.8", "@babel/preset-react": "^7.24.7", "@babel/preset-typescript": "^7.24.7", + "@chromatic-com/storybook": "^1.6.1", + "@storybook/addon-essentials": "^8.2.2", + "@storybook/addon-interactions": "^8.2.2", + "@storybook/addon-links": "^8.2.2", + "@storybook/addon-onboarding": "^8.2.2", + "@storybook/addon-webpack5-compiler-swc": "^1.0.4", + "@storybook/blocks": "^8.2.2", + "@storybook/react": "^8.2.2", + "@storybook/react-webpack5": "^8.2.2", + "@storybook/test": "^8.2.2", + "@tanstack/eslint-plugin-query": "^5.51.1", + "@testing-library/jest-dom": "^6.4.6", + "@testing-library/react": "^16.0.0", + "@testing-library/user-event": "^14.5.2", + "@types/jest": "^29.5.12", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@typescript-eslint/eslint-plugin": "^7.16.0", @@ -32,13 +49,18 @@ "eslint-plugin-react": "^7.34.3", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.8", + "eslint-plugin-storybook": "^0.8.0", "file-loader": "^6.2.0", "fork-ts-checker-webpack-plugin": "^9.0.2", "html-loader": "^5.0.0", "html-webpack-plugin": "^5.6.0", "husky": "^9.0.11", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", "lint-staged": "^15.2.7", + "msw": "^2.3.1", "prettier": "^3.3.2", + "storybook": "^8.2.2", "ts-loader": "^9.5.1", "typescript": "^5.5.3", "webpack": "^5.92.1", @@ -47,11 +69,15 @@ "webpack-merge": "^6.0.1" } }, + "node_modules/@adobe/css-tools": { + "version": "4.4.0", + "dev": true, + "license": "MIT" + }, "node_modules/@ampproject/remapping": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -62,9 +88,8 @@ }, "node_modules/@babel/cli": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.24.8.tgz", - "integrity": "sha512-isdp+G6DpRyKc+3Gqxy2rjzgF7Zj9K0mzLNnxz+E/fgeag8qT3vVulX4gY9dGO1q0y+0lUv6V3a+uhUzMzrwXg==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "commander": "^6.2.0", @@ -91,9 +116,8 @@ }, "node_modules/@babel/cli/node_modules/brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -101,19 +125,16 @@ }, "node_modules/@babel/cli/node_modules/commander": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/@babel/cli/node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -131,9 +152,8 @@ }, "node_modules/@babel/cli/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -143,8 +163,7 @@ }, "node_modules/@babel/code-frame": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "license": "MIT", "dependencies": { "@babel/highlight": "^7.24.7", "picocolors": "^1.0.0" @@ -155,18 +174,16 @@ }, "node_modules/@babel/compat-data": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.8.tgz", - "integrity": "sha512-c4IM7OTg6k1Q+AJ153e2mc2QVTezTwnb4VzquwcyiEzGnW0Kedv4do/TrkU98qPeC5LNiMt/QXwIjzYXLBpyZg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.8.tgz", - "integrity": "sha512-6AWcmZC/MZCO0yKys4uhg5NlxL0ESF3K6IAaoQ+xSXvPyPyxNWRafP+GDbI88Oh68O7QkJgmEtedWPM9U0pZNg==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.7", @@ -194,8 +211,7 @@ }, "node_modules/@babel/generator": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.8.tgz", - "integrity": "sha512-47DG+6F5SzOi0uEvK4wMShmn5yY0mVjVJoWTphdY2B4Rx9wHgjK7Yhtr0ru6nE+sn0v38mzrWOlah0p/YlHHOQ==", + "license": "MIT", "dependencies": { "@babel/types": "^7.24.8", "@jridgewell/gen-mapping": "^0.3.5", @@ -208,9 +224,8 @@ }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.24.7" }, @@ -220,9 +235,8 @@ }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", - "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/traverse": "^7.24.7", "@babel/types": "^7.24.7" @@ -233,9 +247,8 @@ }, "node_modules/@babel/helper-compilation-targets": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz", - "integrity": "sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.24.8", "@babel/helper-validator-option": "^7.24.8", @@ -249,9 +262,8 @@ }, "node_modules/@babel/helper-create-class-features-plugin": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.8.tgz", - "integrity": "sha512-4f6Oqnmyp2PP3olgUMmOwC3akxSm5aBYraQ6YDdKy7NcAMkDECHWG0DEnV6M2UAkERgIBhYt8S27rURPg7SxWA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", "@babel/helper-environment-visitor": "^7.24.7", @@ -272,9 +284,8 @@ }, "node_modules/@babel/helper-create-regexp-features-plugin": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.7.tgz", - "integrity": "sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", "regexpu-core": "^5.3.1", @@ -289,9 +300,8 @@ }, "node_modules/@babel/helper-define-polyfill-provider": { "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", - "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", @@ -305,8 +315,7 @@ }, "node_modules/@babel/helper-environment-visitor": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "license": "MIT", "dependencies": { "@babel/types": "^7.24.7" }, @@ -316,8 +325,7 @@ }, "node_modules/@babel/helper-function-name": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "license": "MIT", "dependencies": { "@babel/template": "^7.24.7", "@babel/types": "^7.24.7" @@ -328,8 +336,7 @@ }, "node_modules/@babel/helper-hoist-variables": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", + "license": "MIT", "dependencies": { "@babel/types": "^7.24.7" }, @@ -339,9 +346,8 @@ }, "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", - "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/traverse": "^7.24.8", "@babel/types": "^7.24.8" @@ -352,8 +358,7 @@ }, "node_modules/@babel/helper-module-imports": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "license": "MIT", "dependencies": { "@babel/traverse": "^7.24.7", "@babel/types": "^7.24.7" @@ -364,9 +369,8 @@ }, "node_modules/@babel/helper-module-transforms": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.8.tgz", - "integrity": "sha512-m4vWKVqvkVAWLXfHCCfff2luJj86U+J0/x+0N3ArG/tP0Fq7zky2dYwMbtPmkc/oulkkbjdL3uWzuoBwQ8R00Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-module-imports": "^7.24.7", @@ -383,9 +387,8 @@ }, "node_modules/@babel/helper-optimise-call-expression": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", - "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.24.7" }, @@ -395,18 +398,16 @@ }, "node_modules/@babel/helper-plugin-utils": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", - "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.7.tgz", - "integrity": "sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", "@babel/helper-environment-visitor": "^7.24.7", @@ -421,9 +422,8 @@ }, "node_modules/@babel/helper-replace-supers": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", - "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-member-expression-to-functions": "^7.24.7", @@ -438,9 +438,8 @@ }, "node_modules/@babel/helper-simple-access": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/traverse": "^7.24.7", "@babel/types": "^7.24.7" @@ -451,9 +450,8 @@ }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", - "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/traverse": "^7.24.7", "@babel/types": "^7.24.7" @@ -464,8 +462,7 @@ }, "node_modules/@babel/helper-split-export-declaration": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "license": "MIT", "dependencies": { "@babel/types": "^7.24.7" }, @@ -475,34 +472,30 @@ }, "node_modules/@babel/helper-string-parser": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", - "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz", - "integrity": "sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-function-name": "^7.24.7", "@babel/template": "^7.24.7", @@ -515,9 +508,8 @@ }, "node_modules/@babel/helpers": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.8.tgz", - "integrity": "sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/template": "^7.24.7", "@babel/types": "^7.24.8" @@ -528,8 +520,7 @@ }, "node_modules/@babel/highlight": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", @@ -542,8 +533,7 @@ }, "node_modules/@babel/parser": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", - "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", + "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -553,9 +543,8 @@ }, "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.7.tgz", - "integrity": "sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-plugin-utils": "^7.24.7" @@ -569,9 +558,8 @@ }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.7.tgz", - "integrity": "sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -584,9 +572,8 @@ }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", - "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", @@ -601,9 +588,8 @@ }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.7.tgz", - "integrity": "sha512-utA4HuR6F4Vvcr+o4DnjL8fCOlgRFGbeeBEGNg3ZTrLFw6VWG5XmUrvcQ0FjIYMU2ST4XcR2Wsp7t9qOAPnxMg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-plugin-utils": "^7.24.7" @@ -617,9 +603,8 @@ }, "node_modules/@babel/plugin-proposal-private-property-in-object": { "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" }, @@ -629,9 +614,19 @@ }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -641,9 +636,8 @@ }, "node_modules/@babel/plugin-syntax-class-properties": { "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -653,9 +647,8 @@ }, "node_modules/@babel/plugin-syntax-class-static-block": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -668,9 +661,8 @@ }, "node_modules/@babel/plugin-syntax-dynamic-import": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -680,9 +672,8 @@ }, "node_modules/@babel/plugin-syntax-export-namespace-from": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.3" }, @@ -690,11 +681,25 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-flow": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.24.7.tgz", + "integrity": "sha512-9G8GYT/dxn/D1IIKOUBmGX0mnmj46mGH9NnZyJLwtCpgh5f7D2VbuKodb+2s9m1Yavh1s7ASQN8lf0eqrb1LTw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-import-assertions": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", - "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -707,9 +712,8 @@ }, "node_modules/@babel/plugin-syntax-import-attributes": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", - "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -722,9 +726,8 @@ }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -734,9 +737,8 @@ }, "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -746,9 +748,8 @@ }, "node_modules/@babel/plugin-syntax-jsx": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", - "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -761,9 +762,8 @@ }, "node_modules/@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -773,9 +773,8 @@ }, "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -785,9 +784,8 @@ }, "node_modules/@babel/plugin-syntax-numeric-separator": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -797,9 +795,8 @@ }, "node_modules/@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -809,9 +806,8 @@ }, "node_modules/@babel/plugin-syntax-optional-catch-binding": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -821,9 +817,8 @@ }, "node_modules/@babel/plugin-syntax-optional-chaining": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -833,9 +828,8 @@ }, "node_modules/@babel/plugin-syntax-private-property-in-object": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -848,9 +842,8 @@ }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -863,9 +856,8 @@ }, "node_modules/@babel/plugin-syntax-typescript": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", - "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -878,9 +870,8 @@ }, "node_modules/@babel/plugin-syntax-unicode-sets-regex": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -894,9 +885,8 @@ }, "node_modules/@babel/plugin-transform-arrow-functions": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", - "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -909,9 +899,8 @@ }, "node_modules/@babel/plugin-transform-async-generator-functions": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.7.tgz", - "integrity": "sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-plugin-utils": "^7.24.7", @@ -927,9 +916,8 @@ }, "node_modules/@babel/plugin-transform-async-to-generator": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", - "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.24.7", "@babel/helper-plugin-utils": "^7.24.7", @@ -944,9 +932,8 @@ }, "node_modules/@babel/plugin-transform-block-scoped-functions": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", - "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -959,9 +946,8 @@ }, "node_modules/@babel/plugin-transform-block-scoping": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.7.tgz", - "integrity": "sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -974,9 +960,8 @@ }, "node_modules/@babel/plugin-transform-class-properties": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz", - "integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.24.7", "@babel/helper-plugin-utils": "^7.24.7" @@ -990,9 +975,8 @@ }, "node_modules/@babel/plugin-transform-class-static-block": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", - "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.24.7", "@babel/helper-plugin-utils": "^7.24.7", @@ -1007,9 +991,8 @@ }, "node_modules/@babel/plugin-transform-classes": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.8.tgz", - "integrity": "sha512-VXy91c47uujj758ud9wx+OMgheXm4qJfyhj1P18YvlrQkNOSrwsteHk+EFS3OMGfhMhpZa0A+81eE7G4QC+3CA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", "@babel/helper-compilation-targets": "^7.24.8", @@ -1029,9 +1012,8 @@ }, "node_modules/@babel/plugin-transform-computed-properties": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", - "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", "@babel/template": "^7.24.7" @@ -1045,9 +1027,8 @@ }, "node_modules/@babel/plugin-transform-destructuring": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz", - "integrity": "sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.8" }, @@ -1060,9 +1041,8 @@ }, "node_modules/@babel/plugin-transform-dotall-regex": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", - "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.24.7", "@babel/helper-plugin-utils": "^7.24.7" @@ -1076,9 +1056,8 @@ }, "node_modules/@babel/plugin-transform-duplicate-keys": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", - "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -1091,9 +1070,8 @@ }, "node_modules/@babel/plugin-transform-dynamic-import": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", - "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", "@babel/plugin-syntax-dynamic-import": "^7.8.3" @@ -1107,9 +1085,8 @@ }, "node_modules/@babel/plugin-transform-exponentiation-operator": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", - "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", "@babel/helper-plugin-utils": "^7.24.7" @@ -1123,9 +1100,8 @@ }, "node_modules/@babel/plugin-transform-export-namespace-from": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", - "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" @@ -1137,11 +1113,26 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-flow-strip-types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.24.7.tgz", + "integrity": "sha512-cjRKJ7FobOH2eakx7Ja+KpJRj8+y+/SiB3ooYm/n2UJfxu0oEaOoxOinitkJcPqv9KxS0kxTGPUaR7L2XcXDXA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-flow": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-for-of": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", - "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" @@ -1155,9 +1146,8 @@ }, "node_modules/@babel/plugin-transform-function-name": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.7.tgz", - "integrity": "sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.24.7", "@babel/helper-function-name": "^7.24.7", @@ -1172,9 +1162,8 @@ }, "node_modules/@babel/plugin-transform-json-strings": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", - "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", "@babel/plugin-syntax-json-strings": "^7.8.3" @@ -1188,9 +1177,8 @@ }, "node_modules/@babel/plugin-transform-literals": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz", - "integrity": "sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -1203,9 +1191,8 @@ }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", - "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" @@ -1219,9 +1206,8 @@ }, "node_modules/@babel/plugin-transform-member-expression-literals": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", - "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -1234,9 +1220,8 @@ }, "node_modules/@babel/plugin-transform-modules-amd": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", - "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.24.7", "@babel/helper-plugin-utils": "^7.24.7" @@ -1250,9 +1235,8 @@ }, "node_modules/@babel/plugin-transform-modules-commonjs": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz", - "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.24.8", "@babel/helper-plugin-utils": "^7.24.8", @@ -1267,9 +1251,8 @@ }, "node_modules/@babel/plugin-transform-modules-systemjs": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.7.tgz", - "integrity": "sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-hoist-variables": "^7.24.7", "@babel/helper-module-transforms": "^7.24.7", @@ -1285,9 +1268,8 @@ }, "node_modules/@babel/plugin-transform-modules-umd": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", - "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.24.7", "@babel/helper-plugin-utils": "^7.24.7" @@ -1301,9 +1283,8 @@ }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", - "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.24.7", "@babel/helper-plugin-utils": "^7.24.7" @@ -1317,9 +1298,8 @@ }, "node_modules/@babel/plugin-transform-new-target": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", - "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -1332,9 +1312,8 @@ }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", - "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" @@ -1348,9 +1327,8 @@ }, "node_modules/@babel/plugin-transform-numeric-separator": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", - "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", "@babel/plugin-syntax-numeric-separator": "^7.10.4" @@ -1364,9 +1342,8 @@ }, "node_modules/@babel/plugin-transform-object-rest-spread": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", - "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.24.7", "@babel/helper-plugin-utils": "^7.24.7", @@ -1382,9 +1359,8 @@ }, "node_modules/@babel/plugin-transform-object-super": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", - "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", "@babel/helper-replace-supers": "^7.24.7" @@ -1398,9 +1374,8 @@ }, "node_modules/@babel/plugin-transform-optional-catch-binding": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", - "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" @@ -1414,9 +1389,8 @@ }, "node_modules/@babel/plugin-transform-optional-chaining": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz", - "integrity": "sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.8", "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", @@ -1431,9 +1405,8 @@ }, "node_modules/@babel/plugin-transform-parameters": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", - "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -1446,9 +1419,8 @@ }, "node_modules/@babel/plugin-transform-private-methods": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz", - "integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.24.7", "@babel/helper-plugin-utils": "^7.24.7" @@ -1462,9 +1434,8 @@ }, "node_modules/@babel/plugin-transform-private-property-in-object": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", - "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", "@babel/helper-create-class-features-plugin": "^7.24.7", @@ -1480,9 +1451,8 @@ }, "node_modules/@babel/plugin-transform-property-literals": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", - "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -1495,9 +1465,8 @@ }, "node_modules/@babel/plugin-transform-react-display-name": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.7.tgz", - "integrity": "sha512-H/Snz9PFxKsS1JLI4dJLtnJgCJRoo0AUm3chP6NYr+9En1JMKloheEiLIhlp5MDVznWo+H3AAC1Mc8lmUEpsgg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -1510,9 +1479,8 @@ }, "node_modules/@babel/plugin-transform-react-jsx": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.24.7.tgz", - "integrity": "sha512-+Dj06GDZEFRYvclU6k4bme55GKBEWUmByM/eoKuqg4zTNQHiApWRhQph5fxQB2wAEFvRzL1tOEj1RJ19wJrhoA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", "@babel/helper-module-imports": "^7.24.7", @@ -1529,9 +1497,8 @@ }, "node_modules/@babel/plugin-transform-react-jsx-development": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.24.7.tgz", - "integrity": "sha512-QG9EnzoGn+Qar7rxuW+ZOsbWOt56FvvI93xInqsZDC5fsekx1AlIO4KIJ5M+D0p0SqSH156EpmZyXq630B8OlQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/plugin-transform-react-jsx": "^7.24.7" }, @@ -1544,9 +1511,8 @@ }, "node_modules/@babel/plugin-transform-react-pure-annotations": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.7.tgz", - "integrity": "sha512-PLgBVk3fzbmEjBJ/u8kFzOqS9tUeDjiaWud/rRym/yjCo/M9cASPlnrd2ZmmZpQT40fOOrvR8jh+n8jikrOhNA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", "@babel/helper-plugin-utils": "^7.24.7" @@ -1560,9 +1526,8 @@ }, "node_modules/@babel/plugin-transform-regenerator": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", - "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", "regenerator-transform": "^0.15.2" @@ -1576,9 +1541,8 @@ }, "node_modules/@babel/plugin-transform-reserved-words": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", - "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -1591,9 +1555,8 @@ }, "node_modules/@babel/plugin-transform-shorthand-properties": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", - "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -1606,9 +1569,8 @@ }, "node_modules/@babel/plugin-transform-spread": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", - "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" @@ -1622,9 +1584,8 @@ }, "node_modules/@babel/plugin-transform-sticky-regex": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", - "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -1637,9 +1598,8 @@ }, "node_modules/@babel/plugin-transform-template-literals": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", - "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -1652,9 +1612,8 @@ }, "node_modules/@babel/plugin-transform-typeof-symbol": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz", - "integrity": "sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.8" }, @@ -1667,9 +1626,8 @@ }, "node_modules/@babel/plugin-transform-typescript": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.8.tgz", - "integrity": "sha512-CgFgtN61BbdOGCP4fLaAMOPkzWUh6yQZNMr5YSt8uz2cZSSiQONCQFWqsE4NeVfOIhqDOlS9CR3WD91FzMeB2Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", "@babel/helper-create-class-features-plugin": "^7.24.8", @@ -1685,9 +1643,8 @@ }, "node_modules/@babel/plugin-transform-unicode-escapes": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", - "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -1700,9 +1657,8 @@ }, "node_modules/@babel/plugin-transform-unicode-property-regex": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", - "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.24.7", "@babel/helper-plugin-utils": "^7.24.7" @@ -1716,9 +1672,8 @@ }, "node_modules/@babel/plugin-transform-unicode-regex": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", - "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.24.7", "@babel/helper-plugin-utils": "^7.24.7" @@ -1732,9 +1687,8 @@ }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz", - "integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.24.7", "@babel/helper-plugin-utils": "^7.24.7" @@ -1748,9 +1702,8 @@ }, "node_modules/@babel/preset-env": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.8.tgz", - "integrity": "sha512-vObvMZB6hNWuDxhSaEPTKCwcqkAIuDtE+bQGn4XMXne1DSLzFVY8Vmj1bm+mUQXYNN8NmaQEO+r8MMbzPr1jBQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.24.8", "@babel/helper-compilation-targets": "^7.24.8", @@ -1841,11 +1794,27 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/preset-flow": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.24.7.tgz", + "integrity": "sha512-NL3Lo0NorCU607zU3NwRyJbpaB6E3t0xtd3LfAQKDfkeX4/ggcDXvkmkW42QWT5owUeW/jAe4hn+2qvkV1IbfQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-transform-flow-strip-types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/preset-modules": { "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/types": "^7.4.4", @@ -1857,9 +1826,8 @@ }, "node_modules/@babel/preset-react": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.7.tgz", - "integrity": "sha512-AAH4lEkpmzFWrGVlHaxJB7RLH21uPQ9+He+eFLWHmF9IuFQVugz8eAsamaW0DXRrTfco5zj1wWtpdcXJUOfsag==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", "@babel/helper-validator-option": "^7.24.7", @@ -1877,9 +1845,8 @@ }, "node_modules/@babel/preset-typescript": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz", - "integrity": "sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", "@babel/helper-validator-option": "^7.24.7", @@ -1894,16 +1861,105 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/register": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.24.6.tgz", + "integrity": "sha512-WSuFCc2wCqMeXkz/i3yfAAsxwWflEgbVkZzivgAmXl/MxrXeoYFZOOPllbC8R8WTF7u61wSRQtDVZ1879cdu6w==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "find-cache-dir": "^2.0.0", + "make-dir": "^2.1.0", + "pirates": "^4.0.6", + "source-map-support": "^0.5.16" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/register/node_modules/find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/register/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/register/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/register/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/register/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/register/node_modules/pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@babel/regjsgen": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@babel/runtime": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", - "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -1913,8 +1969,7 @@ }, "node_modules/@babel/template": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.24.7", "@babel/parser": "^7.24.7", @@ -1926,8 +1981,7 @@ }, "node_modules/@babel/traverse": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz", - "integrity": "sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==", + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.24.7", "@babel/generator": "^7.24.8", @@ -1946,8 +2000,7 @@ }, "node_modules/@babel/types": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.8.tgz", - "integrity": "sha512-SkSBEHwwJRU52QEVZBmMBnE5Ux2/6WU1grdYyOhpbCNxbmJrDuDCphBzKZSO3taf0zztp+qkWlymE5tVL5l0TA==", + "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", @@ -1957,19 +2010,96 @@ "node": ">=6.9.0" } }, + "node_modules/@base2/pretty-print-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz", + "integrity": "sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA==", + "dev": true + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@bundled-es-modules/cookie": { + "version": "2.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "cookie": "^0.5.0" + } + }, + "node_modules/@bundled-es-modules/cookie/node_modules/cookie": { + "version": "0.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@bundled-es-modules/statuses": { + "version": "1.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "statuses": "^2.0.1" + } + }, + "node_modules/@chromatic-com/storybook": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@chromatic-com/storybook/-/storybook-1.6.1.tgz", + "integrity": "sha512-x1x1NB3j4xpfeSWKr96emc+7ZvfsvH+/WVb3XCjkB24PPbT8VZXb3mJSAQMrSzuQ8+eQE9kDogYHH9Fj3tb/Cw==", + "dev": true, + "dependencies": { + "chromatic": "^11.4.0", + "filesize": "^10.0.12", + "jsonfile": "^6.1.0", + "react-confetti": "^6.1.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=16.0.0", + "yarn": ">=1.22.18" + } + }, + "node_modules/@chromatic-com/storybook/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@chromatic-com/storybook/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" } }, "node_modules/@emotion/babel-plugin": { "version": "11.11.0", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", - "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.16.7", "@babel/runtime": "^7.18.3", @@ -1986,13 +2116,11 @@ }, "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + "license": "MIT" }, "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -2002,16 +2130,14 @@ }, "node_modules/@emotion/babel-plugin/node_modules/source-map": { "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/@emotion/cache": { "version": "11.11.0", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", - "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "license": "MIT", "dependencies": { "@emotion/memoize": "^0.8.1", "@emotion/sheet": "^1.2.2", @@ -2022,18 +2148,15 @@ }, "node_modules/@emotion/hash": { "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", - "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + "license": "MIT" }, "node_modules/@emotion/memoize": { "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", - "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + "license": "MIT" }, "node_modules/@emotion/react": { "version": "11.11.4", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", - "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.11.0", @@ -2055,8 +2178,7 @@ }, "node_modules/@emotion/serialize": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.4.tgz", - "integrity": "sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ==", + "license": "MIT", "dependencies": { "@emotion/hash": "^0.9.1", "@emotion/memoize": "^0.8.1", @@ -2067,3375 +2189,10025 @@ }, "node_modules/@emotion/sheet": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", - "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + "license": "MIT" }, "node_modules/@emotion/unitless": { "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", - "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + "license": "MIT" }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", - "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "license": "MIT", "peerDependencies": { "react": ">=16.8.0" } }, "node_modules/@emotion/utils": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", - "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + "license": "MIT" }, "node_modules/@emotion/weak-memoize": { "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", - "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "license": "MIT" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, + "optional": true, + "os": [ + "aix" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + "node": ">=12" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], "dev": true, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "node": ">=12" } }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=12" } }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "*" + "node": ">=12" } }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], "dev": true, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=12" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=10.10.0" + "node": ">=12" } }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "*" + "node": ">=12" } }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": ">=12" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], "dev": true, - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { "node": ">=12" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.0.0" + "node": ">=12" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.0.0" + "node": ">=12" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.0.0" + "node": ">=12" } }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@jsonjoy.com/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], "dev": true, + "optional": true, + "os": [ + "sunos" + ], "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": ">=12" } }, - "node_modules/@jsonjoy.com/json-pack": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.0.4.tgz", - "integrity": "sha512-aOcSN4MeAtFROysrbqG137b7gaDDSmVrl5mpo6sT/w+kcXpWnzhMjmY/Fh/sDx26NBxyIE7MB1seqLeCAzy9Sg==", + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@jsonjoy.com/base64": "^1.1.1", - "@jsonjoy.com/util": "^1.1.2", - "hyperdyperid": "^1.2.0", - "thingies": "^1.20.0" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": ">=12" } }, - "node_modules/@jsonjoy.com/util": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.2.0.tgz", - "integrity": "sha512-4B8B+3vFsY4eo33DMKyJPlQ3sBMpPFUZK2dr3O3rXrOGKKbYG44J0XSFkDo1VOQiri5HFEhIeVvItjR2xcazmg==", + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], "dev": true, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": ">=12" } }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", - "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", - "dev": true - }, - "node_modules/@nicolo-ribaudo/chokidar-2": { - "version": "2.1.8-no-fsevents.3", - "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz", - "integrity": "sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==", + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", "dev": true, + "license": "MIT", "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": ">= 8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/@eslint-community/regexpp": { + "version": "4.11.0", "dev": true, + "license": "MIT", "engines": { - "node": ">= 8" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", "dev": true, + "license": "MIT", "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, "engines": { - "node": ">= 8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", "dev": true, - "optional": true, - "engines": { - "node": ">=14" + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", "dev": true, + "license": "MIT", "dependencies": { - "@types/connect": "*", - "@types/node": "*" + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", "dev": true, + "license": "ISC", "dependencies": { - "@types/node": "*" + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "node_modules/@eslint/js": { + "version": "8.57.0", "dev": true, - "dependencies": { - "@types/node": "*" + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" } }, - "node_modules/@types/eslint": { - "version": "8.56.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", - "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", "dev": true, + "license": "MIT", "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", "dev": true, + "license": "ISC", "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, - "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", "dev": true, - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@types/express-serve-static-core": { - "version": "4.19.5", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", - "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@inquirer/confirm": { + "version": "3.1.14", "dev": true, + "license": "MIT", "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" + "@inquirer/core": "^9.0.2", + "@inquirer/type": "^1.4.0" + }, + "engines": { + "node": ">=18" } }, - "node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", - "dev": true - }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "dev": true + "node_modules/@inquirer/core": { + "version": "9.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/figures": "^1.0.3", + "@inquirer/type": "^1.4.0", + "@types/mute-stream": "^0.0.4", + "@types/node": "^20.14.9", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "cli-spinners": "^2.9.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } }, - "node_modules/@types/http-proxy": { - "version": "1.17.14", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", - "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "node_modules/@inquirer/core/node_modules/ansi-escapes": { + "version": "4.3.2", "dev": true, + "license": "MIT", "dependencies": { - "@types/node": "*" + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true - }, - "node_modules/@types/node": { - "version": "20.14.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", - "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "node_modules/@inquirer/core/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@types/node-forge": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", - "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "node_modules/@inquirer/core/node_modules/color-convert": { + "version": "2.0.1", "dev": true, + "license": "MIT", "dependencies": { - "@types/node": "*" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" - }, - "node_modules/@types/prop-types": { - "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", - "dev": true - }, - "node_modules/@types/qs": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", - "dev": true + "node_modules/@inquirer/core/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true + "node_modules/@inquirer/core/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" }, - "node_modules/@types/react": { - "version": "18.3.3", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", - "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "node_modules/@inquirer/core/node_modules/signal-exit": { + "version": "4.1.0", "dev": true, - "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.0.2" + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@types/react-dom": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", - "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "node_modules/@inquirer/core/node_modules/string-width": { + "version": "4.2.3", "dev": true, + "license": "MIT", "dependencies": { - "@types/react": "*" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@types/retry": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", - "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", - "dev": true - }, - "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "node_modules/@inquirer/core/node_modules/type-fest": { + "version": "0.21.3", "dev": true, - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "node_modules/@inquirer/core/node_modules/wrap-ansi": { + "version": "6.2.0", "dev": true, + "license": "MIT", "dependencies": { - "@types/express": "*" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "node_modules/@inquirer/figures": { + "version": "1.0.3", "dev": true, - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" + "license": "MIT", + "engines": { + "node": ">=18" } }, - "node_modules/@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "node_modules/@inquirer/type": { + "version": "1.4.0", "dev": true, + "license": "MIT", "dependencies": { - "@types/node": "*" + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" } }, - "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", - "dev": true, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "dev": true, + "license": "ISC", "dependencies": { - "@types/node": "*" + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" } }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.0.tgz", - "integrity": "sha512-py1miT6iQpJcs1BiJjm54AMzeuMPBSPuKPlnT8HlfudbcS5rYeX5jajpLf3mrdRh9dA/Ec2FVUY0ifeVNDIhZw==", + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", "dev": true, - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.16.0", - "@typescript-eslint/type-utils": "7.16.0", - "@typescript-eslint/utils": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" - }, + "license": "MIT", "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": ">=12" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/@typescript-eslint/parser": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.0.tgz", - "integrity": "sha512-ar9E+k7CU8rWi2e5ErzQiC93KKEFAXA2Kky0scAlPcxYblLt8+XZuHUZwlyfXILyQa95P6lQg+eZgh/dDs3+Vw==", + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "7.16.0", - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/typescript-estree": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0", - "debug": "^4.3.4" + "ansi-regex": "^6.0.1" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": ">=12" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" }, - "peerDependencies": { - "eslint": "^8.56.0" + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.0.tgz", - "integrity": "sha512-8gVv3kW6n01Q6TrI1cmTZ9YMFi3ucDT7i7aI5lEikk2ebk1AEjrwX8MDTdaX5D7fPXMBLvnsaa0IFTAu+jcfOw==", + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0" + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/console/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.0.tgz", - "integrity": "sha512-j0fuUswUjDHfqV/UdW6mLtOQQseORqfdmoBNDFOqs9rvNVR2e+cmu6zJu/Ku4SDuqiJko6YnhwcL8x45r8Oqxg==", + "node_modules/@jest/console/node_modules/chalk": { + "version": "4.1.2", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "7.16.0", - "@typescript-eslint/utils": "7.16.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "engines": { + "node": ">=7.0.0" } }, - "node_modules/@typescript-eslint/types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.0.tgz", - "integrity": "sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==", + "node_modules/@jest/console/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@jest/console/node_modules/slash": { + "version": "3.0.0", "dev": true, + "license": "MIT", "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": ">=8" + } + }, + "node_modules/@jest/console/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "engines": { + "node": ">=8" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.0.tgz", - "integrity": "sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==", + "node_modules/@jest/core": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" }, "peerDependenciesMeta": { - "typescript": { + "node-notifier": { "optional": true } } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "node_modules/@jest/core/node_modules/ansi-escapes": { + "version": "4.3.2", "dev": true, - "bin": { - "semver": "bin/semver.js" + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" }, "engines": { - "node": ">=10" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@typescript-eslint/utils": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.0.tgz", - "integrity": "sha512-PqP4kP3hb4r7Jav+NiRCntlVzhxBNWq6ZQ+zQwII1y/G/1gdIPeYDCKr2+dH6049yJQsWZiHU6RlwvIFBXXGNA==", + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.16.0", - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/typescript-estree": "7.16.0" + "color-convert": "^2.0.1" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": ">=8" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz", - "integrity": "sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==", + "node_modules/@jest/core/node_modules/chalk": { + "version": "4.1.2", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.16.0", - "eslint-visitor-keys": "^3.4.3" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "node_modules/@jest/core/node_modules/color-convert": { + "version": "2.0.1", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true + "node_modules/@jest/core/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", - "dev": true + "node_modules/@jest/core/node_modules/slash": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "node_modules/@jest/core/node_modules/supports-color": { + "version": "7.2.0", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true + "node_modules/@jest/core/node_modules/type-fest": { + "version": "0.21.3", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "node_modules/@jest/environment": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "node_modules/@jest/expect": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "@xtuc/ieee754": "^1.2.0" + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "node_modules/@jest/expect-utils": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "@xtuc/long": "4.2.2" + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "node_modules/@jest/fake-timers": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "node_modules/@jest/globals": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "node_modules/@jest/reporters": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "node_modules/@jest/reporters/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "node_modules/@jest/reporters/node_modules/brace-expansion": { + "version": "1.1.11", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@xtuc/long": "4.2.2" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@webpack-cli/configtest": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", - "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "4.1.2", "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, "engines": { - "node": ">=14.15.0" + "node": ">=10" }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@webpack-cli/info": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", - "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "node_modules/@jest/reporters/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", "dev": true, - "engines": { - "node": ">=14.15.0" + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" + "engines": { + "node": ">=8" } }, - "node_modules/@webpack-cli/serve": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", - "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "node_modules/@jest/reporters/node_modules/color-convert": { + "version": "2.0.1", "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } + "engines": { + "node": ">=7.0.0" } }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true + "node_modules/@jest/reporters/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "node_modules/@jest/reporters/node_modules/glob": { + "version": "7.2.3", "dev": true, + "license": "ISC", "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">= 0.6" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "node_modules/@jest/reporters/node_modules/jest-worker": { + "version": "29.7.0", "dev": true, - "bin": { - "acorn": "bin/acorn" + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, "engines": { - "node": ">=0.4.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "node_modules/@jest/reporters/node_modules/minimatch": { + "version": "3.1.2", "dev": true, - "peerDependencies": { - "acorn": "^8" + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "node_modules/@jest/reporters/node_modules/slash": { + "version": "3.0.0", "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/@jest/schemas": { + "version": "29.6.3", "dev": true, + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "@sinclair/typebox": "^0.27.8" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "node_modules/@jest/source-map": { + "version": "29.6.3", "dev": true, + "license": "MIT", "dependencies": { - "ajv": "^8.0.0" + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" }, - "peerDependencies": { - "ajv": "^8.0.0" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/ajv-formats/node_modules/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==", - "dev": true + "node_modules/@jest/test-sequencer/node_modules/slash": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "node_modules/@jest/transform": { + "version": "29.7.0", "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/ansi-escapes": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", - "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", + "node_modules/@jest/transform/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">=14.16" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "node_modules/@jest/transform/node_modules/chalk": { + "version": "4.1.2", "dev": true, - "engines": [ - "node >= 0.8.0" - ], - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "node_modules/@jest/transform/node_modules/color-convert": { + "version": "2.0.1", "dev": true, + "license": "MIT", "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "color-name": "~1.1.4" }, "engines": { - "node": ">= 8" + "node": ">=7.0.0" } }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "node_modules/@jest/transform/node_modules/color-name": { + "version": "1.1.4", "dev": true, - "dependencies": { - "deep-equal": "^2.0.5" - } + "license": "MIT" }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "node_modules/@jest/transform/node_modules/slash": { + "version": "3.0.0", "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, + "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true - }, - "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "node_modules/@jest/transform/node_modules/supports-color": { + "version": "7.2.0", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" + "has-flag": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, "engines": { "node": ">=8" } }, - "node_modules/array.prototype.findlast": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", - "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "node_modules/@jest/types": { + "version": "29.6.3", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "node_modules/@jest/types/node_modules/color-convert": { + "version": "2.0.1", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "color-name": "~1.1.4" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=7.0.0" } }, - "node_modules/array.prototype.toreversed": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", - "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", + "node_modules/@jest/types/node_modules/color-name": { + "version": "1.1.4", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - } + "license": "MIT" }, - "node_modules/array.prototype.tosorted": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", - "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "node_modules/@jest/types/node_modules/supports-color": { + "version": "7.2.0", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.3", - "es-errors": "^1.3.0", - "es-shim-unscopables": "^1.0.2" + "has-flag": "^4.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=8" } }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6.0.0" } }, - "node_modules/ast-types-flow": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", - "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", - "dev": true - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6.0.0" } }, - "node_modules/axe-core": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.9.1.tgz", - "integrity": "sha512-QbUdXJVTpvUTHU7871ppZkdOLBeGUKBQWHkHrvN2V9IQWGMt61zf3B45BtzjxEJzYuj0JBjBZP/hmYS/R9pmAw==", - "dev": true, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=6.0.0" } }, - "node_modules/axobject-query": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", - "integrity": "sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==", + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", "dev": true, + "license": "MIT", "dependencies": { - "deep-equal": "^2.0.5" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, - "node_modules/babel-loader": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", - "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", - "dev": true, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "license": "MIT", "dependencies": { - "find-cache-dir": "^4.0.0", - "schema-utils": "^4.0.0" - }, + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">= 14.15.0" + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" }, "peerDependencies": { - "@babel/core": "^7.12.0", - "webpack": ">=5" + "tslib": "2" } }, - "node_modules/babel-loader/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.0.4", "dev": true, + "license": "Apache-2.0", "dependencies": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "@jsonjoy.com/base64": "^1.1.1", + "@jsonjoy.com/util": "^1.1.2", + "hyperdyperid": "^1.2.0", + "thingies": "^1.20.0" + }, + "engines": { + "node": ">=10.0" }, "funding": { "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" } }, - "node_modules/babel-loader/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "node_modules/@jsonjoy.com/util": { + "version": "1.2.0", "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" }, "peerDependencies": { - "ajv": "^8.8.2" + "tslib": "2" } }, - "node_modules/babel-loader/node_modules/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==", - "dev": true + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "dev": true, + "license": "MIT" }, - "node_modules/babel-loader/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "node_modules/@mdx-js/react": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.0.1.tgz", + "integrity": "sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" + "@types/mdx": "^2.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" } }, - "node_modules/babel-plugin-macros": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", - "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "cosmiconfig": "^7.0.0", - "resolve": "^1.19.0" - }, + "node_modules/@mswjs/cookies": { + "version": "1.1.1", + "dev": true, + "license": "MIT", "engines": { - "node": ">=10", - "npm": ">=6" + "node": ">=18" } }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", - "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "node_modules/@mswjs/interceptors": { + "version": "0.29.1", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.2", - "semver": "^6.3.1" + "@open-draft/deferred-promise": "^2.2.0", + "@open-draft/logger": "^0.3.0", + "@open-draft/until": "^2.0.0", + "is-node-process": "^1.2.0", + "outvariant": "^1.2.1", + "strict-event-emitter": "^0.5.1" }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + "engines": { + "node": ">=18" } }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", - "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", + "node_modules/@nicolo-ribaudo/chokidar-2": { + "version": "2.1.8-no-fsevents.3", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1", - "core-js-compat": "^3.36.1" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + "engines": { + "node": ">= 8" } }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", - "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + "engines": { + "node": ">= 8" } }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "node_modules/@open-draft/deferred-promise": { + "version": "2.2.0", + "dev": true, + "license": "MIT" }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", - "dev": true + "node_modules/@open-draft/logger": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-node-process": "^1.2.0", + "outvariant": "^1.4.0" + } }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "node_modules/@open-draft/until": { + "version": "2.1.0", "dev": true, + "license": "MIT" + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "dev": true, + "license": "MIT", + "optional": true, "engines": { - "node": "*" + "node": ">=14" } }, - "node_modules/binary-extensions": { + "node_modules/@remix-run/router": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.17.1.tgz", + "integrity": "sha512-mCOMec4BKd6BRGBZeSnGiIgwsbLGp3yhVqAD8H+PxiRNEHgDpZb8J1TnrSDlg97t0ySKMQJTHCWBCmBpSmkF6Q==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "dev": true, + "license": "MIT" + }, + "node_modules/@sindresorhus/merge-streams": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", "dev": true, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "node_modules/@sinonjs/commons": { + "version": "3.0.1", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "type-detect": "4.0.8" } }, - "node_modules/body-parser/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", "dev": true, - "engines": { - "node": ">= 0.8" + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0" } }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/@storybook/addon-actions": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.2.2.tgz", + "integrity": "sha512-SN4cSRt3f0qXi5te+yhMseSdQuZntA8lGlASbRmN77YQTpIaGsNiH88xFoky0s9qz531hiRfU1R0ZSMylBwSKw==", "dev": true, "dependencies": { - "ms": "2.0.0" + "@storybook/global": "^5.0.0", + "@types/uuid": "^9.0.1", + "dequal": "^2.0.2", + "polished": "^4.2.2", + "uuid": "^9.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.2" } }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "node_modules/@storybook/addon-actions/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } }, - "node_modules/bonjour-service": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", - "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "node_modules/@storybook/addon-backgrounds": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.2.2.tgz", + "integrity": "sha512-m/xJe7uKL+kfJx7pQcHwAeIvJ3tdLIpDGrMAVDNDJHcAxfe44cFjIInaV/1HKf3y5Awap+DZFW66ekkxuI9zzA==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" + "@storybook/global": "^5.0.0", + "memoizerific": "^1.11.3", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.2" } }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true + "node_modules/@storybook/addon-controls": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.2.2.tgz", + "integrity": "sha512-y241aOANGzT5XBADUIvALwG/xF5eC6UItzmWJaFvOzSBCq74GIA0+Hu9atyFdvFQbXOrdvPWC4jR+9iuBFRxAA==", + "dev": true, + "dependencies": { + "dequal": "^2.0.2", + "lodash": "^4.17.21", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.2" + } }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "node_modules/@storybook/addon-docs": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.2.2.tgz", + "integrity": "sha512-qk/yjAR9RpsSrKLLbeCgb6u58c8TmYqyJSnXgbAozZZNKHBWlIpvZ/hTNYud8qo0coPlxnLdjnZf32TykWGlAg==", "dev": true, "dependencies": { - "balanced-match": "^1.0.0" + "@babel/core": "^7.24.4", + "@mdx-js/react": "^3.0.0", + "@storybook/blocks": "8.2.2", + "@storybook/csf-plugin": "8.2.2", + "@storybook/global": "^5.0.0", + "@storybook/react-dom-shim": "8.2.2", + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "fs-extra": "^11.1.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", + "rehype-external-links": "^3.0.0", + "rehype-slug": "^6.0.0", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.2" } }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "node_modules/@storybook/addon-docs/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, "dependencies": { - "fill-range": "^7.1.1" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">=8" + "node": ">=14.14" } }, - "node_modules/browserslist": { - "version": "4.23.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", - "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", + "node_modules/@storybook/addon-essentials": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.2.2.tgz", + "integrity": "sha512-yN//BFMbSvNV0+Sll2hcKmgJX06TUKQDm6pZimUjkXczFtOmK7K/UdDmKjWS+qjhfJdWpxdRoEpxoHvvRmNfsA==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "dependencies": { - "caniuse-lite": "^1.0.30001640", - "electron-to-chromium": "^1.4.820", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.1.0" + "@storybook/addon-actions": "8.2.2", + "@storybook/addon-backgrounds": "8.2.2", + "@storybook/addon-controls": "8.2.2", + "@storybook/addon-docs": "8.2.2", + "@storybook/addon-highlight": "8.2.2", + "@storybook/addon-measure": "8.2.2", + "@storybook/addon-outline": "8.2.2", + "@storybook/addon-toolbars": "8.2.2", + "@storybook/addon-viewport": "8.2.2", + "ts-dedent": "^2.0.0" }, - "bin": { - "browserslist": "cli.js" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + "peerDependencies": { + "storybook": "^8.2.2" } }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/bundle-name": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", - "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "node_modules/@storybook/addon-highlight": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.2.2.tgz", + "integrity": "sha512-yDTRzzL+IJAymgY32xoZl09BGBVmPOUV2wVNGYcZkkBLvz2GSQMTfUe1/7F4jAx//+rFBu48/MQzsTC7Bk8kPw==", "dev": true, "dependencies": { - "run-applescript": "^7.0.0" - }, - "engines": { - "node": ">=18" + "@storybook/global": "^5.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.2" } }, - "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "node_modules/@storybook/addon-interactions": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.2.2.tgz", + "integrity": "sha512-zRRuUwm/l41JtTUgjIoQTUgLT99Hsdz9cqKca/8NYo1MGBdEcKE41DH4aBIzKaOKFu7p9q00/o/X1EqYX4LMUA==", "dev": true, - "engines": { - "node": ">= 0.8" + "dependencies": { + "@storybook/global": "^5.0.0", + "@storybook/instrumenter": "8.2.2", + "@storybook/test": "8.2.2", + "polished": "^4.2.2", + "ts-dedent": "^2.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.2" } }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "node_modules/@storybook/addon-links": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-8.2.2.tgz", + "integrity": "sha512-eGh7O7SgTJMtnuXC0HlRPOegu1njcJS2cnVqjbzjvjxsPSBhbHpdYMi9Q9E7al/FKuqMUOjIR9YLIlmK1AJaqA==", "dev": true, "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "@storybook/csf": "0.1.11", + "@storybook/global": "^5.0.0", + "ts-dedent": "^2.0.0" }, - "engines": { - "node": ">= 0.4" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "storybook": "^8.2.2" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + } + } + }, + "node_modules/@storybook/addon-measure": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.2.2.tgz", + "integrity": "sha512-3rCo/aMltt5FrBVdr2dYlD8HlE2q9TLKGJZnwh9on4QyL6ArHbdYw0LmyHe/LrFahJ49w1XQZBMSJcAdRkkS7w==", + "dev": true, + "dependencies": { + "@storybook/global": "^5.0.0", + "tiny-invariant": "^1.3.1" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.2" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "engines": { - "node": ">=6" + "node_modules/@storybook/addon-onboarding": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-onboarding/-/addon-onboarding-8.2.2.tgz", + "integrity": "sha512-dCdE8Mt/JW6cq6dY7co35Sul/bAkUT3ixaxBrUagFUYUQ/PTYM6p4/B+45RURD5S9z8LVHH1rVgmEeScm3U78w==", + "dev": true, + "dependencies": { + "react-confetti": "^6.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.2" } }, - "node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "node_modules/@storybook/addon-outline": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.2.2.tgz", + "integrity": "sha512-Y+PQtfTNO8GLX5nz+3x5AMfHNvdGvBXazJ29+Rl1ygYN1+Q9ZhRJDE1kAK0wLxb7CG14peAgdYEaQb3Rduv7HQ==", "dev": true, "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" + "@storybook/global": "^5.0.0", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.2" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001641", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001641.tgz", - "integrity": "sha512-Phv5thgl67bHYo1TtMY/MurjkHhV4EDaCosezRXgZ8jzA/Ub+wjxAvbGvjoFENStinwi5kCyOYV3mi5tOGykwA==", + "node_modules/@storybook/addon-toolbars": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.2.2.tgz", + "integrity": "sha512-JGOueOc3EPljlCl9dVSQee0aMYoqGNvN0UH+R6wYJ3bDZ+tUG/iYpsZVPUOvS8vzp3Imk5Is1kzQbQYJtzdGLg==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.2" + } }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/@storybook/addon-viewport": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.2.2.tgz", + "integrity": "sha512-gkZ8bsjGGP0NuevkT2iKC+szezSy+w4BrBDknf490mRU2K/B2e7TGojf/j/AtxzILMzD4IKzKUXbE/zwcqjZvA==", + "dev": true, "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "memoizerific": "^1.11.3" }, - "engines": { - "node": ">=4" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.2" } }, - "node_modules/chalk/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/@storybook/addon-webpack5-compiler-swc": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-webpack5-compiler-swc/-/addon-webpack5-compiler-swc-1.0.4.tgz", + "integrity": "sha512-S/ypdAK9oqwUAt3ZOn44qi3RWdH5uBLbBgtfHSXckqTpQRu7F7A9bRzjK+H5ti4xVADRhxu/xzIBwxWgcCeIXA==", + "dev": true, + "dependencies": { + "@swc/core": "1.5.7", + "swc-loader": "^0.2.3" + }, "engines": { - "node": ">=4" + "node": ">=18" } }, - "node_modules/chalk/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/@storybook/blocks": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.2.2.tgz", + "integrity": "sha512-av0Tryg4toDl2L/d1ABErtsAk9wvM1su6+M4wq5/Go50sk5IjGTldhbZFa9zNOohxLkZwaj0Q5xAgJ1Y+m5KrQ==", + "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "@storybook/csf": "0.1.11", + "@storybook/global": "^5.0.0", + "@storybook/icons": "^1.2.5", + "@types/lodash": "^4.14.167", + "color-convert": "^2.0.1", + "dequal": "^2.0.2", + "lodash": "^4.17.21", + "markdown-to-jsx": "^7.4.5", + "memoizerific": "^1.11.3", + "polished": "^4.2.2", + "react-colorful": "^5.1.2", + "telejson": "^7.2.0", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" }, - "engines": { - "node": ">=4" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "storybook": "^8.2.2" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } } }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "node_modules/@storybook/blocks/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": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "color-name": "~1.1.4" }, "engines": { - "node": ">= 8.10.0" + "node": ">=7.0.0" + } + }, + "node_modules/@storybook/blocks/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/@storybook/builder-webpack5": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-8.2.2.tgz", + "integrity": "sha512-ud6a3pRusbC/TvT1ed15INxSivyL2y2zI61O/MWQZmM8sZOIC6ObdHLtzU4+535IIqiXhPoQ/QiOBbejqjgZvw==", + "dev": true, + "dependencies": { + "@storybook/core-webpack": "8.2.2", + "@types/node": "^18.0.0", + "@types/semver": "^7.3.4", + "browser-assert": "^1.2.1", + "case-sensitive-paths-webpack-plugin": "^2.4.0", + "cjs-module-lexer": "^1.2.3", + "constants-browserify": "^1.0.0", + "css-loader": "^6.7.1", + "es-module-lexer": "^1.5.0", + "express": "^4.19.2", + "fork-ts-checker-webpack-plugin": "^8.0.0", + "fs-extra": "^11.1.0", + "html-webpack-plugin": "^5.5.0", + "magic-string": "^0.30.5", + "path-browserify": "^1.0.1", + "process": "^0.11.10", + "semver": "^7.3.7", + "style-loader": "^3.3.1", + "terser-webpack-plugin": "^5.3.1", + "ts-dedent": "^2.0.0", + "url": "^0.11.0", + "util": "^0.12.4", + "util-deprecate": "^1.0.2", + "webpack": "5", + "webpack-dev-middleware": "^6.1.2", + "webpack-hot-middleware": "^2.25.1", + "webpack-virtual-modules": "^0.6.0" }, "funding": { - "url": "https://paulmillr.com/funding/" + "type": "opencollective", + "url": "https://opencollective.com/storybook" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "peerDependencies": { + "storybook": "^8.2.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "node_modules/@storybook/builder-webpack5/node_modules/@types/node": { + "version": "18.19.39", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz", + "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==", "dev": true, - "engines": { - "node": ">=6.0" + "dependencies": { + "undici-types": "~5.26.4" } }, - "node_modules/clean-css": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", - "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", + "node_modules/@storybook/builder-webpack5/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "dependencies": { - "source-map": "~0.6.0" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, - "engines": { - "node": ">= 10.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "node_modules/@storybook/builder-webpack5/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, "dependencies": { - "restore-cursor": "^4.0.0" + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/@storybook/builder-webpack5/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": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/cli-truncate": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", - "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "node_modules/@storybook/builder-webpack5/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { - "slice-ansi": "^5.0.0", - "string-width": "^7.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@storybook/builder-webpack5/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=18" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/cli-truncate/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "node_modules/@storybook/builder-webpack5/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, - "engines": { - "node": ">=12" + "dependencies": { + "color-name": "~1.1.4" }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "engines": { + "node": ">=7.0.0" } }, - "node_modules/cli-truncate/node_modules/emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "node_modules/@storybook/builder-webpack5/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/cli-truncate/node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "node_modules/@storybook/builder-webpack5/node_modules/fork-ts-checker-webpack-plugin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-8.0.0.tgz", + "integrity": "sha512-mX3qW3idpueT2klaQXBzrIM/pHw+T0B/V9KHEvNrqijTq9NFnMZU6oreVxDYcf33P8a5cW+67PjodNHthGnNVg==", "dev": true, "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" + "@babel/code-frame": "^7.16.7", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "cosmiconfig": "^7.0.1", + "deepmerge": "^4.2.2", + "fs-extra": "^10.0.0", + "memfs": "^3.4.1", + "minimatch": "^3.0.4", + "node-abort-controller": "^3.0.1", + "schema-utils": "^3.1.1", + "semver": "^7.3.5", + "tapable": "^2.2.1" }, "engines": { - "node": ">=18" + "node": ">=12.13.0", + "yarn": ">=1.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "typescript": ">3.6.0", + "webpack": "^5.11.0" } }, - "node_modules/cli-truncate/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "node_modules/@storybook/builder-webpack5/node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "dependencies": { - "ansi-regex": "^6.0.1" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "node_modules/@storybook/builder-webpack5/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">=6" + "node": ">=14.14" } }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/@storybook/builder-webpack5/node_modules/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==", + "dev": true + }, + "node_modules/@storybook/builder-webpack5/node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dev": true, "dependencies": { - "color-name": "1.1.3" + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" } }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "node_modules/@storybook/builder-webpack5/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } }, - "node_modules/common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", - "dev": true + "node_modules/@storybook/builder-webpack5/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "node_modules/@storybook/builder-webpack5/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": { - "mime-db": ">= 1.43.0 < 2" + "has-flag": "^4.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "node_modules/@storybook/builder-webpack5/node_modules/webpack-dev-middleware": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.1.3.tgz", + "integrity": "sha512-A4ChP0Qj8oGociTs6UdlRUGANIGrCDL3y+pmQMc+dSsraXHCatFpmMey4mYELA+juqwUqwQsUgJJISXl1KWmiw==", "dev": true, "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" + "colorette": "^2.0.10", + "memfs": "^3.4.12", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } } }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/@storybook/builder-webpack5/node_modules/webpack-dev-middleware/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, "dependencies": { - "ms": "2.0.0" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "node_modules/@storybook/codemod": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-8.2.2.tgz", + "integrity": "sha512-wRUVKLHVUhbLJYKW3QOufUxJGwaUT4jTCD8+HOGpHPdJO3NrwXu186xt4tuPZO2Y/NnacPeCQPsaK5ok4O8o7A==", "dev": true, - "engines": { - "node": ">=0.8" + "dependencies": { + "@babel/core": "^7.24.4", + "@babel/preset-env": "^7.24.4", + "@babel/types": "^7.24.0", + "@storybook/core": "8.2.2", + "@storybook/csf": "0.1.11", + "@types/cross-spawn": "^6.0.2", + "cross-spawn": "^7.0.3", + "globby": "^14.0.1", + "jscodeshift": "^0.15.1", + "lodash": "^4.17.21", + "prettier": "^3.1.1", + "recast": "^0.23.5", + "tiny-invariant": "^1.3.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" } }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "node_modules/@storybook/codemod/node_modules/globby": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", "dev": true, "dependencies": { - "safe-buffer": "5.2.1" + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "node_modules/@storybook/codemod/node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "node_modules/@storybook/codemod/node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true - }, - "node_modules/core-js": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz", - "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==", + "node_modules/@storybook/core": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.2.2.tgz", + "integrity": "sha512-L4ojYI+Os/i5bCReDIlFgEDQSS94mbJlNU9WRzEGZpqNC5/hbFEC9Tip7P1MiRx9NrewkzU7b+UCP7mi3e4drQ==", "dev": true, - "hasInstallScript": true, + "dependencies": { + "@storybook/csf": "0.1.11", + "@types/express": "^4.17.21", + "@types/node": "^18.0.0", + "browser-assert": "^1.2.1", + "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0", + "esbuild-register": "^3.5.0", + "express": "^4.19.2", + "process": "^0.11.10", + "recast": "^0.23.5", + "util": "^0.12.4", + "ws": "^8.2.3" + }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/core-js" + "url": "https://opencollective.com/storybook" } }, - "node_modules/core-js-compat": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", - "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", + "node_modules/@storybook/core-webpack": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-8.2.2.tgz", + "integrity": "sha512-M5wzgNbotVXcfo7WkXIuDxcBl7tTjnQ27lmlSBk+cu63pDvNn4UMDan621FcvxWq2DbjgIj+PASZ4DzM5O+ovA==", "dev": true, "dependencies": { - "browserslist": "^4.23.0" + "@types/node": "^18.0.0", + "ts-dedent": "^2.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/core-js" + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.2" } }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "node_modules/@storybook/core-webpack/node_modules/@types/node": { + "version": "18.19.39", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz", + "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } }, - "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "node_modules/@storybook/core/node_modules/@types/node": { + "version": "18.19.39", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz", + "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==", + "dev": true, "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" + "undici-types": "~5.26.4" } }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "node_modules/@storybook/csf": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.1.11.tgz", + "integrity": "sha512-dHYFQH3mA+EtnCkHXzicbLgsvzYjcDJ1JWsogbItZogkPHgSJM/Wr71uMkcvw8v9mmCyP4NpXJuu6bPoVsOnzg==", "dev": true, "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" + "type-fest": "^2.19.0" } }, - "node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "node_modules/@storybook/csf-plugin": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.2.2.tgz", + "integrity": "sha512-3K2RUpDDvq3DT46qAIj2VBC+fzTTebRUcZUsRfS6G1AzaX9p25iClEHiwcJacFkgQKhkci8A/Ly3Z4JJ3b4Pgw==", "dev": true, "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" + "unplugin": "^1.3.1" }, "funding": { - "url": "https://github.com/sponsors/fb55" + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.2" } }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "node_modules/@storybook/csf/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "dev": true, "engines": { - "node": ">= 6" + "node": ">=12.20" }, "funding": { - "url": "https://github.com/sponsors/fb55" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" - }, - "node_modules/damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "node_modules/@storybook/global": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@storybook/global/-/global-5.0.0.tgz", + "integrity": "sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==", "dev": true }, - "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "node_modules/@storybook/icons": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@storybook/icons/-/icons-1.2.9.tgz", + "integrity": "sha512-cOmylsz25SYXaJL/gvTk/dl3pyk7yBFRfeXTsHvTA3dfhoU/LWSq0NKL9nM7WBasJyn6XPSGnLS4RtKXLw5EUg==", "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, "engines": { - "node": ">= 0.4" + "node": ">=14.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "node_modules/@storybook/instrumenter": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.2.2.tgz", + "integrity": "sha512-refwnHqKHhya45MgqakhMG0jKhTiEIAl0aOwAaQy9+zf9ncMIYQAXRQsSZ2Z188lFWE24wbeHKteb62a5ZfWwQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" + "@storybook/global": "^5.0.0", + "@vitest/utils": "^1.3.1", + "util": "^0.12.4" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.2" } }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "node_modules/@storybook/preset-react-webpack": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/preset-react-webpack/-/preset-react-webpack-8.2.2.tgz", + "integrity": "sha512-GJkDtw4Ac8icD66fotGXYE3rmZkIwASpNLOeGzyP4eMMNaf5vlvTDxwkY551cGbnA5P7r4UkGjDiWinB9XE4VQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "@storybook/core-webpack": "8.2.2", + "@storybook/react": "8.2.2", + "@storybook/react-docgen-typescript-plugin": "1.0.6--canary.9.0c3f3b7.0", + "@types/node": "^18.0.0", + "@types/semver": "^7.3.4", + "find-up": "^5.0.0", + "fs-extra": "^11.1.0", + "magic-string": "^0.30.5", + "react-docgen": "^7.0.0", + "resolve": "^1.22.8", + "semver": "^7.3.7", + "tsconfig-paths": "^4.2.0", + "webpack": "5" }, "engines": { - "node": ">= 0.4" + "node": ">=18.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dependencies": { - "ms": "2.1.2" + "type": "opencollective", + "url": "https://opencollective.com/storybook" }, - "engines": { - "node": ">=6.0" + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "storybook": "^8.2.2" }, "peerDependenciesMeta": { - "supports-color": { + "typescript": { "optional": true } } }, - "node_modules/deep-equal": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", - "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "node_modules/@storybook/preset-react-webpack/node_modules/@types/node": { + "version": "18.19.39", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz", + "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==", "dev": true, "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.5", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.2", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.13" + "undici-types": "~5.26.4" + } + }, + "node_modules/@storybook/preset-react-webpack/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/deep-equal/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "node_modules/@storybook/preset-react-webpack/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "node_modules/@storybook/preset-react-webpack/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/default-browser": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", - "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "node_modules/@storybook/preset-react-webpack/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "dependencies": { - "bundle-name": "^4.1.0", - "default-browser-id": "^5.0.0" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=18" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/default-browser-id": { + "node_modules/@storybook/preset-react-webpack/node_modules/p-locate": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", - "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, "engines": { - "node": ">=18" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "node_modules/@storybook/preset-react-webpack/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "execa": "^5.0.0" + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">= 10" + "node": ">=10" } }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "node_modules/@storybook/preset-react-webpack/node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", "dev": true, "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6" } }, - "node_modules/define-lazy-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "node_modules/@storybook/preset-react-webpack/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "node_modules/@storybook/react": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.2.2.tgz", + "integrity": "sha512-U4p/RV78yhjEwEzem8U7wE5/3sSpnqreGsPdAHMCIHd69e9tVeF0rwrTJGp917RClPjBKgEcfelCuvOlby4MrA==", "dev": true, "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" + "@storybook/global": "^5.0.0", + "@storybook/react-dom-shim": "8.2.2", + "@types/escodegen": "^0.0.6", + "@types/estree": "^0.0.51", + "@types/node": "^18.0.0", + "acorn": "^7.4.1", + "acorn-jsx": "^5.3.1", + "acorn-walk": "^7.2.0", + "escodegen": "^2.1.0", + "html-tags": "^3.1.0", + "lodash": "^4.17.21", + "prop-types": "^15.7.2", + "react-element-to-jsx-string": "^15.0.0", + "semver": "^7.3.7", + "ts-dedent": "^2.0.0", + "type-fest": "~2.19", + "util-deprecate": "^1.0.2" }, "engines": { - "node": ">= 0.4" + "node": ">=18.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "storybook": "^8.2.2", + "typescript": ">= 4.2.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "node_modules/@storybook/react-docgen-typescript-plugin": { + "version": "1.0.6--canary.9.0c3f3b7.0", + "resolved": "https://registry.npmjs.org/@storybook/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.6--canary.9.0c3f3b7.0.tgz", + "integrity": "sha512-KUqXC3oa9JuQ0kZJLBhVdS4lOneKTOopnNBK4tUAgoxWQ3u/IjzdueZjFr7gyBrXMoU6duutk3RQR9u8ZpYJ4Q==", "dev": true, - "engines": { - "node": ">= 0.8" + "dependencies": { + "debug": "^4.1.1", + "endent": "^2.0.1", + "find-cache-dir": "^3.3.1", + "flat-cache": "^3.0.4", + "micromatch": "^4.0.2", + "react-docgen-typescript": "^2.2.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "typescript": ">= 4.x", + "webpack": ">= 4" } }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "node_modules/@storybook/react-docgen-typescript-plugin/node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "node_modules/@storybook/react-docgen-typescript-plugin/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "dependencies": { - "path-type": "^4.0.0" + "semver": "^6.0.0" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "node_modules/@storybook/react-dom-shim": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.2.2.tgz", + "integrity": "sha512-4fb1/yT9WXHzHjs0In6orIEZxga5eXd9UaXEFGudBgowCjDUVP9LabDdKTbGusz20lfaAkATsRG/W+EcSLoh8w==", "dev": true, - "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" }, - "engines": { - "node": ">=6" + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "storybook": "^8.2.2" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "node_modules/@storybook/react-webpack5": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/react-webpack5/-/react-webpack5-8.2.2.tgz", + "integrity": "sha512-JPR2Lp88KbfRWgnAd4lKFRKuc9Up6YeqbaDb6sptOXXzDM4nOhlRXKqp2tIqyhfiKp3wmu3PksixqD8f8VS9CA==", "dev": true, "dependencies": { - "esutils": "^2.0.2" + "@storybook/builder-webpack5": "8.2.2", + "@storybook/preset-react-webpack": "8.2.2", + "@storybook/react": "8.2.2", + "@types/node": "^18.0.0" }, "engines": { - "node": ">=6.0.0" + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "storybook": "^8.2.2", + "typescript": ">= 4.2.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "node_modules/@storybook/react-webpack5/node_modules/@types/node": { + "version": "18.19.39", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz", + "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==", "dev": true, "dependencies": { - "utila": "~0.4" + "undici-types": "~5.26.4" } }, - "node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "node_modules/@storybook/react/node_modules/@types/estree": { + "version": "0.0.51", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", + "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", + "dev": true + }, + "node_modules/@storybook/react/node_modules/@types/node": { + "version": "18.19.39", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz", + "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==", "dev": true, "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + "undici-types": "~5.26.4" } }, - "node_modules/dom-serializer/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "node_modules/@storybook/react/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" } }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "node_modules/@storybook/react/node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] + "engines": { + "node": ">=0.4.0" + } }, - "node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "node_modules/@storybook/react/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "domelementtype": "^2.2.0" + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">= 4" + "node": ">=10" + } + }, + "node_modules/@storybook/react/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true, + "engines": { + "node": ">=12.20" }, "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "node_modules/@storybook/test": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.2.2.tgz", + "integrity": "sha512-X2qAKErjTh1X7XLAZqCMtU0ZK8JuwdKmgiqU0oXWxIDmCX6/Dm9ZIcdMZHs/S+K/UnIByjNlQpTShLVfRUeN1w==", "dev": true, "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" + "@storybook/csf": "0.1.11", + "@storybook/instrumenter": "8.2.2", + "@testing-library/dom": "10.1.0", + "@testing-library/jest-dom": "6.4.5", + "@testing-library/user-event": "14.5.2", + "@vitest/expect": "1.6.0", + "@vitest/spy": "1.6.0", + "util": "^0.12.4" }, "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.2" } }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "node_modules/@storybook/test/node_modules/@testing-library/dom": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.1.0.tgz", + "integrity": "sha512-wdsYKy5zupPyLCW2Je5DLHSxSfbIp6h80WoHOQc+RPtmPGA52O9x5MJEkv92Sjonpq+poOAtUKhh1kBGAXBrNA==", "dev": true, "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true - }, - "node_modules/electron-to-chromium": { - "version": "1.4.825", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.825.tgz", - "integrity": "sha512-OCcF+LwdgFGcsYPYC5keEEFC2XT0gBhrYbeGzHCx7i9qRFbzO/AqTmc/C/1xNhJj+JA7rzlN7mpBuStshh96Cg==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true, + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, "engines": { - "node": ">= 4" + "node": ">=18" } }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "node_modules/@storybook/test/node_modules/@testing-library/jest-dom": { + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.5.tgz", + "integrity": "sha512-AguB9yvTXmCnySBP1lWjfNNUwpbElsaQ567lt2VdGqAdHtpieLgjmcVyv1q7PMIvLbgpDdkWV5Ydv3FEejyp2A==", "dev": true, + "dependencies": { + "@adobe/css-tools": "^4.3.2", + "@babel/runtime": "^7.9.2", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "lodash": "^4.17.21", + "redent": "^3.0.0" + }, "engines": { - "node": ">= 0.8" + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + }, + "peerDependencies": { + "@jest/globals": ">= 28", + "@types/bun": "latest", + "@types/jest": ">= 28", + "jest": ">= 28", + "vitest": ">= 0.32" + }, + "peerDependenciesMeta": { + "@jest/globals": { + "optional": true + }, + "@types/bun": { + "optional": true + }, + "@types/jest": { + "optional": true + }, + "jest": { + "optional": true + }, + "vitest": { + "optional": true + } } }, - "node_modules/enhanced-resolve": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", - "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "node_modules/@storybook/test/node_modules/@testing-library/jest-dom/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=10.13.0" + "node": ">=8" } }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "node_modules/@storybook/test/node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true + }, + "node_modules/@storybook/test/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": ">=0.12" + "node": ">=8" }, "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/envinfo": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", - "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", + "node_modules/@storybook/test/node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dependencies": { - "is-arrayish": "^0.2.1" + "dequal": "^2.0.3" } }, - "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "node_modules/@storybook/test/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "node_modules/@storybook/test/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": { - "get-intrinsic": "^1.2.4" + "color-name": "~1.1.4" }, "engines": { - "node": ">= 0.4" + "node": ">=7.0.0" } }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "node_modules/@storybook/test/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/@storybook/test/node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, "engines": { - "node": ">= 0.4" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/es-get-iterator": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", - "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "node_modules/@storybook/test/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "is-arguments": "^1.1.1", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.7", - "isarray": "^2.0.5", - "stop-iteration-iterator": "^1.0.0" + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/es-get-iterator/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "node_modules/@storybook/test/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "node_modules/es-iterator-helpers": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", - "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", + "node_modules/@storybook/test/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": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.3", - "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.0.3", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.7", - "iterator.prototype": "^1.1.2", - "safe-array-concat": "^1.1.2" + "has-flag": "^4.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=8" } }, - "node_modules/es-module-lexer": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", - "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", - "dev": true - }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "node_modules/@swc/core": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.5.7.tgz", + "integrity": "sha512-U4qJRBefIJNJDRCCiVtkfa/hpiZ7w0R6kASea+/KLp+vkus3zcLSB8Ub8SvKgTIxjWpwsKcZlPf5nrv4ls46SQ==", "dev": true, + "hasInstallScript": true, "dependencies": { - "es-errors": "^1.3.0" + "@swc/counter": "^0.1.2", + "@swc/types": "0.1.7" }, "engines": { - "node": ">= 0.4" + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.5.7", + "@swc/core-darwin-x64": "1.5.7", + "@swc/core-linux-arm-gnueabihf": "1.5.7", + "@swc/core-linux-arm64-gnu": "1.5.7", + "@swc/core-linux-arm64-musl": "1.5.7", + "@swc/core-linux-x64-gnu": "1.5.7", + "@swc/core-linux-x64-musl": "1.5.7", + "@swc/core-win32-arm64-msvc": "1.5.7", + "@swc/core-win32-ia32-msvc": "1.5.7", + "@swc/core-win32-x64-msvc": "1.5.7" + }, + "peerDependencies": { + "@swc/helpers": "^0.5.0" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } } }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "node_modules/@swc/core-darwin-arm64": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.5.7.tgz", + "integrity": "sha512-bZLVHPTpH3h6yhwVl395k0Mtx8v6CGhq5r4KQdAoPbADU974Mauz1b6ViHAJ74O0IVE5vyy7tD3OpkQxL/vMDQ==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">= 0.4" + "node": ">=10" } }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "node_modules/@swc/core-darwin-x64": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.5.7.tgz", + "integrity": "sha512-RpUyu2GsviwTc2qVajPL0l8nf2vKj5wzO3WkLSHAHEJbiUZk83NJrZd1RVbEknIMO7+Uyjh54hEh8R26jSByaw==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "hasown": "^2.0.0" + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" } }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.5.7.tgz", + "integrity": "sha512-cTZWTnCXLABOuvWiv6nQQM0hP6ZWEkzdgDvztgHI/+u/MvtzJBN5lBQ2lue/9sSFYLMqzqff5EHKlFtrJCA9dQ==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=10" } }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.5.7.tgz", + "integrity": "sha512-hoeTJFBiE/IJP30Be7djWF8Q5KVgkbDtjySmvYLg9P94bHg9TJPSQoC72tXx/oXOgXvElDe/GMybru0UxhKx4g==", + "cpu": [ + "arm64" + ], "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.5.7.tgz", + "integrity": "sha512-+NDhK+IFTiVK1/o7EXdCeF2hEzCiaRSrb9zD7X2Z7inwWlxAntcSuzZW7Y6BRqGQH89KA91qYgwbnjgTQ22PiQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.5.7.tgz", + "integrity": "sha512-25GXpJmeFxKB+7pbY7YQLhWWjkYlR+kHz5I3j9WRl3Lp4v4UD67OGXwPe+DIcHqcouA1fhLhsgHJWtsaNOMBNg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=0.8.0" + "node": ">=10" } }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.5.7.tgz", + "integrity": "sha512-0VN9Y5EAPBESmSPPsCJzplZHV26akC0sIgd3Hc/7S/1GkSMoeuVL+V9vt+F/cCuzr4VidzSkqftdP3qEIsXSpg==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=10" } }, - "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.5.7.tgz", + "integrity": "sha512-RtoNnstBwy5VloNCvmvYNApkTmuCe4sNcoYWpmY7C1+bPR+6SOo8im1G6/FpNem8AR5fcZCmXHWQ+EUmRWJyuA==", + "cpu": [ + "arm64" + ], "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.5.7.tgz", + "integrity": "sha512-Xm0TfvcmmspvQg1s4+USL3x8D+YPAfX2JHygvxAnCJ0EHun8cm2zvfNBcsTlnwYb0ybFWXXY129aq1wgFC9TpQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.5.7.tgz", + "integrity": "sha512-tp43WfJLCsKLQKBmjmY/0vv1slVywR5Q4qKjF5OIY8QijaEW7/8VwPyUyVoJZEnDgv9jKtUTG5PzqtIYPZGnyg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "dev": true + }, + "node_modules/@swc/types": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.7.tgz", + "integrity": "sha512-scHWahbHF0eyj3JsxG9CFJgFdFNaVQCNAimBlT6PzS3n/HptxqREjsm4OH6AN3lYcffZYSPxXW8ua2BEHp0lJQ==", + "dev": true, + "dependencies": { + "@swc/counter": "^0.1.3" + } + }, + "node_modules/@tanstack/eslint-plugin-query": { + "version": "5.51.1", + "resolved": "https://registry.npmjs.org/@tanstack/eslint-plugin-query/-/eslint-plugin-query-5.51.1.tgz", + "integrity": "sha512-M1IBJTtD9V69Zf4Efnkizg+DKdn4yTt+OfD0my5hZRok4wPZ44+Y8XNUFpwy6nsEV/Qt+KsS8IWPjd+eERQUSA==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "8.0.0-alpha.30" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { - "eslint": ">=7.0.0" + "eslint": "^8 || ^9" } }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "node_modules/@tanstack/eslint-plugin-query/node_modules/@typescript-eslint/scope-manager": { + "version": "8.0.0-alpha.30", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.0.0-alpha.30.tgz", + "integrity": "sha512-FGW/iPWGyPFamAVZ60oCAthMqQrqafUGebF8UKuq/ha+e9SVG6YhJoRzurlQXOVf8dHfOhJ0ADMXyFnMc53clg==", "dev": true, "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" + "@typescript-eslint/types": "8.0.0-alpha.30", + "@typescript-eslint/visitor-keys": "8.0.0-alpha.30" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/@tanstack/eslint-plugin-query/node_modules/@typescript-eslint/types": { + "version": "8.0.0-alpha.30", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.0.0-alpha.30.tgz", + "integrity": "sha512-4WzLlw27SO9pK9UFj/Hu7WGo8WveT0SEiIpFVsV2WwtQmLps6kouwtVCB8GJPZKJyurhZhcqCoQVQFmpv441Vg==", "dev": true, - "dependencies": { - "ms": "^2.1.1" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "node_modules/@tanstack/eslint-plugin-query/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.0.0-alpha.30", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.0.0-alpha.30.tgz", + "integrity": "sha512-WSXbc9ZcXI+7yC+6q95u77i8FXz6HOLsw3ST+vMUlFy1lFbXyFL/3e6HDKQCm2Clt0krnoCPiTGvIn+GkYPn4Q==", "dev": true, "dependencies": { - "debug": "^3.2.7" + "@typescript-eslint/types": "8.0.0-alpha.30", + "@typescript-eslint/visitor-keys": "8.0.0-alpha.30", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": ">=4" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependenciesMeta": { - "eslint": { + "typescript": { "optional": true } } }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/@tanstack/eslint-plugin-query/node_modules/@typescript-eslint/utils": { + "version": "8.0.0-alpha.30", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.0.0-alpha.30.tgz", + "integrity": "sha512-rfhqfLqFyXhHNDwMnHiVGxl/Z2q/3guQ1jLlGQ0hi9Rb7inmwz42crM+NnLPR+2vEnwyw1P/g7fnQgQ3qvFx4g==", "dev": true, "dependencies": { - "ms": "^2.1.1" + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.0.0-alpha.30", + "@typescript-eslint/types": "8.0.0-alpha.30", + "@typescript-eslint/typescript-estree": "8.0.0-alpha.30" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" } }, - "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "node_modules/@tanstack/eslint-plugin-query/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.0.0-alpha.30", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.0.0-alpha.30.tgz", + "integrity": "sha512-XZuNurZxBqmr6ZIRIwWFq7j5RZd6ZlkId/HZEWyfciK+CWoyOxSF9Pv2VXH9Rlu2ZG2PfbhLz2Veszl4Pfn7yA==", "dev": true, "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" + "@typescript-eslint/types": "8.0.0-alpha.30", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": ">=4" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@tanstack/eslint-plugin-query/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, + "node_modules/@tanstack/query-core": { + "version": "5.51.1", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.51.1.tgz", + "integrity": "sha512-fJBMQMpo8/KSsWW5ratJR5+IFr7YNJ3K2kfP9l5XObYHsgfVy1w3FJUWU4FT2fj7+JMaEg33zOcNDBo0LMwHnw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.51.1", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.51.1.tgz", + "integrity": "sha512-s47HKFnQ4HOJAHoIiXcpna/roMMPZJPy6fJ6p4ZNVn8+/onlLBEDd1+xc8OnDuwgvecqkZD7Z2mnSRbcWefrKw==", "dependencies": { - "ms": "^2.1.1" + "@tanstack/query-core": "5.51.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18.0.0" } }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "node_modules/@testing-library/dom": { + "version": "10.3.1", "dev": true, + "license": "MIT", + "peer": true, "dependencies": { - "esutils": "^2.0.2" + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" }, "engines": { - "node": ">=0.10.0" + "node": ">=18" } }, - "node_modules/eslint-plugin-import/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@testing-library/dom/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "license": "MIT", + "peer": true, "dependencies": { - "brace-expansion": "^1.1.7" + "color-convert": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/eslint-plugin-jsx-a11y": { + "node_modules/@testing-library/dom/node_modules/aria-query": { + "version": "5.3.0", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/@testing-library/dom/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "peer": 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/@testing-library/dom/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@testing-library/dom/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@testing-library/dom/node_modules/pretty-format": { + "version": "27.5.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@testing-library/dom/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@testing-library/dom/node_modules/react-is": { + "version": "17.0.2", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@testing-library/dom/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.4.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "@babel/runtime": "^7.9.2", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "lodash": "^4.17.21", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + }, + "peerDependencies": { + "@jest/globals": ">= 28", + "@types/bun": "latest", + "@types/jest": ">= 28", + "jest": ">= 28", + "vitest": ">= 0.32" + }, + "peerDependenciesMeta": { + "@jest/globals": { + "optional": true + }, + "@types/bun": { + "optional": true + }, + "@types/jest": { + "optional": true + }, + "jest": { + "optional": true + }, + "vitest": { + "optional": true + } + } + }, + "node_modules/@testing-library/jest-dom/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/chalk": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/jest-dom/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/react": { + "version": "16.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0", + "@types/react-dom": "^18.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@testing-library/user-event": { + "version": "14.5.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/cross-spawn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-fXRhhUkG4H3TQk5dBhQ7m/JDdSNHKwR2BBia62lhwEIq9xGiQKLxd6LymNhn47SjXhsUEPmxi+PKw2OkW4LLjA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/doctrine": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/@types/doctrine/-/doctrine-0.0.9.tgz", + "integrity": "sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==", + "dev": true + }, + "node_modules/@types/emscripten": { + "version": "1.39.13", + "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.39.13.tgz", + "integrity": "sha512-cFq+fO/isvhvmuP/+Sl4K4jtU6E23DoivtbO4r50e3odaxAiVdbfSYRDdJ4gCdxx+3aRjhphS5ZMwIH4hFy/Cw==", + "dev": true + }, + "node_modules/@types/escodegen": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/escodegen/-/escodegen-0.0.6.tgz", + "integrity": "sha512-AjwI4MvWx3HAOaZqYsjKWyEObT9lcVV0Y0V8nXo6cXzN8ZiMxVhf6F3d/UNvXVGKrEzL/Dluc5p+y9GkzlTWig==", + "dev": true + }, + "node_modules/@types/eslint": { + "version": "8.56.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/express": { + "version": "4.17.21", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.14", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.12", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/jsdom": { + "version": "20.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/tough-cookie": "*", + "parse5": "^7.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/lodash": { + "version": "4.17.6", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.6.tgz", + "integrity": "sha512-OpXEVoCKSS3lQqjx9GGGOapBeuW5eUboYHRlHP9urXPX25IKZ6AnP5ZRxtVf63iieUbsHxLn8NQ5Nlftc6yzAA==", + "dev": true + }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mute-stream": { + "version": "0.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "20.14.10", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.12", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/qs": { + "version": "6.9.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/resolve": { + "version": "1.20.6", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.6.tgz", + "integrity": "sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==", + "dev": true + }, + "node_modules/@types/retry": { + "version": "0.12.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/statuses": { + "version": "2.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==", + "dev": true + }, + "node_modules/@types/uuid": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", + "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", + "dev": true + }, + "node_modules/@types/wrap-ansi": { + "version": "3.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.5.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.32", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.16.0", + "@typescript-eslint/type-utils": "7.16.0", + "@typescript-eslint/utils": "7.16.0", + "@typescript-eslint/visitor-keys": "7.16.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.16.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "7.16.0", + "@typescript-eslint/types": "7.16.0", + "@typescript-eslint/typescript-estree": "7.16.0", + "@typescript-eslint/visitor-keys": "7.16.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "7.16.0", + "@typescript-eslint/visitor-keys": "7.16.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "7.16.0", + "@typescript-eslint/utils": "7.16.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.16.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "7.16.0", + "@typescript-eslint/visitor-keys": "7.16.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.6.2", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.16.0", + "@typescript-eslint/types": "7.16.0", + "@typescript-eslint/typescript-estree": "7.16.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "7.16.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "dev": true, + "license": "ISC" + }, + "node_modules/@vitest/expect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz", + "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==", + "dev": true, + "dependencies": { + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", + "chai": "^4.3.10" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz", + "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==", + "dev": true, + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz", + "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==", + "dev": true, + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@yarnpkg/fslib": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@yarnpkg/fslib/-/fslib-2.10.3.tgz", + "integrity": "sha512-41H+Ga78xT9sHvWLlFOZLIhtU6mTGZ20pZ29EiZa97vnxdohJD2AF42rCoAoWfqUz486xY6fhjMH+DYEM9r14A==", + "dev": true, + "dependencies": { + "@yarnpkg/libzip": "^2.3.0", + "tslib": "^1.13.0" + }, + "engines": { + "node": ">=12 <14 || 14.2 - 14.9 || >14.10.0" + } + }, + "node_modules/@yarnpkg/fslib/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/@yarnpkg/libzip": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/libzip/-/libzip-2.3.0.tgz", + "integrity": "sha512-6xm38yGVIa6mKm/DUCF2zFFJhERh/QWp1ufm4cNUvxsONBmfPg8uZ9pZBdOmF6qFGr/HlT6ABBkCSx/dlEtvWg==", + "dev": true, + "dependencies": { + "@types/emscripten": "^1.39.6", + "tslib": "^1.13.0" + }, + "engines": { + "node": ">=12 <14 || 14.2 - 14.9 || >14.10.0" + } + }, + "node_modules/@yarnpkg/libzip/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/abab": { + "version": "2.0.6", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/accepts": { + "version": "1.3.8", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-escapes": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.1.3", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/array-includes": { + "version": "3.1.8", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.toreversed": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/ast-types": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", + "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "dev": true, + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.9.1", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "3.1.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/babel-core": { + "version": "7.0.0-bridge.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", + "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==", + "dev": true, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "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-jest/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/babel-jest/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/babel-jest/node_modules/slash": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-jest/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-loader": { + "version": "9.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-loader/node_modules/ajv": { + "version": "8.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/babel-loader/node_modules/ajv-keywords": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/babel-loader/node_modules/json-schema-traverse": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/babel-loader/node_modules/schema-utils": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.11", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.1", + "core-js-compat": "^3.36.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/batch": { + "version": "0.6.1", + "dev": true, + "license": "MIT" + }, + "node_modules/big.js": { + "version": "5.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/body-parser": { + "version": "1.20.2", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/bonjour-service": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-assert": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/browser-assert/-/browser-assert-1.2.1.tgz", + "integrity": "sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==", + "dev": true + }, + "node_modules/browserslist": { + "version": "4.23.2", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001640", + "electron-to-chromium": "^1.4.820", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.1.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001641", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/case-sensitive-paths-webpack-plugin": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", + "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/chai": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/has-flag": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chromatic": { + "version": "11.5.5", + "resolved": "https://registry.npmjs.org/chromatic/-/chromatic-11.5.5.tgz", + "integrity": "sha512-YS0GJwegF0vpMbwZE68/xJlI4SlUGMqI78V2ATAF19YwTHaq8jGP1CPQGKUSlgWUhzPtyu3ELy6Dvv/owYljAg==", + "dev": true, + "bin": { + "chroma": "dist/bin.js", + "chromatic": "dist/bin.js", + "chromatic-cli": "dist/bin.js" + }, + "peerDependencies": { + "@chromatic-com/cypress": "^0.*.* || ^1.0.0", + "@chromatic-com/playwright": "^0.*.* || ^1.0.0" + }, + "peerDependenciesMeta": { + "@chromatic-com/cypress": { + "optional": true + }, + "@chromatic-com/playwright": { + "optional": true + } + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/citty": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz", + "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", + "dev": true, + "dependencies": { + "consola": "^3.2.3" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/clean-css": { + "version": "5.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "10.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/cliui/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/co": { + "version": "4.6.0", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "1.9.3", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "dev": true, + "license": "MIT" + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "node_modules/compressible": { + "version": "2.0.18", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/confbox": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", + "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==", + "dev": true + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/consola": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.2.3.tgz", + "integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==", + "dev": true, + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.6.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/core-js": { + "version": "3.37.1", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.37.1", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/create-jest": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/create-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/create-jest/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "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/create-jest/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/create-jest/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/create-jest/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", + "dev": true, + "dependencies": { + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/crypto-random-string/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/css-loader": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", + "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", + "dev": true, + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-loader/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/css-select": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "dev": true, + "license": "MIT" + }, + "node_modules/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, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssom": { + "version": "0.5.0", + "dev": true, + "license": "MIT" + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.1.3", + "license": "MIT" + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/data-urls": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.3.5", + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.4.3", + "dev": true, + "license": "MIT" + }, + "node_modules/dedent": { + "version": "1.5.3", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-equal": { + "version": "2.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-equal/node_modules/isarray": { + "version": "2.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/deep-is": { + "version": "0.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-browser": { + "version": "5.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "dev": true + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "dev": true, + "license": "MIT" + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "dev": true, + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domexception": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/domhandler": { + "version": "4.3.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.825", + "dev": true, + "license": "ISC" + }, + "node_modules/emittery": { + "version": "0.13.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "dev": true, + "license": "MIT" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/endent": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/endent/-/endent-2.1.0.tgz", + "integrity": "sha512-r8VyPX7XL8U01Xgnb1CjZ3XV+z90cXIJ9JPE/R9SEC9vpw2P6CfsRPJmp20DppC5N7ZAMCmjYkJIa744Iyg96w==", + "dev": true, + "dependencies": { + "dedent": "^0.7.0", + "fast-json-parse": "^1.0.3", + "objectorarray": "^1.0.5" + } + }, + "node_modules/endent/node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true + }, + "node_modules/enhanced-resolve": { + "version": "5.17.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/envinfo": { + "version": "7.13.0", + "dev": true, + "license": "MIT", + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.23.3", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-get-iterator/node_modules/isarray": { + "version": "2.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/es-iterator-helpers": { + "version": "1.0.19", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/esbuild-register": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.5.0.tgz", + "integrity": "sha512-+4G/XmakeBAsvJuDugJvtyF1x+XJT4FMocynNpxrvEBViirpfUn2PgNpCHedfWhF4WokNsO/OvMKrmJOIJsI5A==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "peerDependencies": { + "esbuild": ">=0.12 <1" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.1", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.29.1", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { "version": "6.9.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.9.0.tgz", - "integrity": "sha512-nOFOCaJG2pYqORjK19lqPqxMO/JpvdCZdPtNdxY3kvom3jTvkAbOvQvD8wuD0G8BYR0IGAGYDlzqWJOh/ybn2g==", "dev": true, + "license": "MIT", + "dependencies": { + "aria-query": "~5.1.3", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.9.1", + "axobject-query": "~3.1.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "es-iterator-helpers": "^1.0.19", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.0" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.34.3", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.toreversed": "^1.1.2", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.19", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.hasown": "^1.1.4", + "object.values": "^1.2.0", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.11" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.8", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=7" + } + }, + "node_modules/eslint-plugin-react/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-storybook": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-0.8.0.tgz", + "integrity": "sha512-CZeVO5EzmPY7qghO2t64oaFM+8FTaD4uzOEjHKp516exyTKo+skKAL9GI3QALS2BXhyALJjNtwbmr1XinGE8bA==", + "dev": true, + "dependencies": { + "@storybook/csf": "^0.0.1", + "@typescript-eslint/utils": "^5.62.0", + "requireindex": "^1.2.0", + "ts-dedent": "^2.2.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "eslint": ">=6" + } + }, + "node_modules/eslint-plugin-storybook/node_modules/@storybook/csf": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.0.1.tgz", + "integrity": "sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.15" + } + }, + "node_modules/eslint-plugin-storybook/node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-storybook/node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-storybook/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-storybook/node_modules/@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-storybook/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-storybook/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "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/eslint/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.2.2", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.24.0", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/yocto-queue": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/express": { + "version": "4.19.2", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-parse": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fast-json-parse/-/fast-json-parse-1.0.3.tgz", + "integrity": "sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.17.1", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fd-package-json": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fd-package-json/-/fd-package-json-1.2.0.tgz", + "integrity": "sha512-45LSPmWf+gC5tdCQMNH4s9Sr00bIkiD9aN7dc5hqkrEw1geRYyDQS1v1oMHAW3ysfxfndqGsrDREHHjNNbKUfA==", + "dev": true, + "dependencies": { + "walk-up-path": "^3.0.1" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-loader": { + "version": "6.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/filesize": { + "version": "10.1.4", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.4.tgz", + "integrity": "sha512-ryBwPIIeErmxgPnm6cbESAzXjuEFubs+yKYLBZvg3CaiNcmkJChoOGcBSrZ6IwkMwPABwPpVXE6IlNdGJJrvEg==", + "dev": true, + "engines": { + "node": ">= 10.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/find-cache-dir": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-dir/node_modules/find-up": { + "version": "6.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-dir/node_modules/locate-path": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-dir/node_modules/p-limit": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-dir/node_modules/p-locate": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-dir/node_modules/path-exists": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/find-cache-dir/node_modules/pkg-dir": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/flat-cache/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flat-cache/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "dev": true, + "license": "ISC" + }, + "node_modules/flow-parser": { + "version": "0.239.1", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.239.1.tgz", + "integrity": "sha512-topOrETNxJ6T2gAnQiWqAlzGPj8uI2wtmNOlDIMNB+qyvGJZ6R++STbUOTAYmvPhOMz2gXnXPH0hOvURYmrBow==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/foreground-child": { + "version": "3.2.1", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "9.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.16.7", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "cosmiconfig": "^8.2.0", + "deepmerge": "^4.2.2", + "fs-extra": "^10.0.0", + "memfs": "^3.4.1", + "minimatch": "^3.0.4", + "node-abort-controller": "^3.0.1", + "schema-utils": "^3.1.1", + "semver": "^7.3.5", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">=12.13.0", + "yarn": ">=1.0.0" + }, + "peerDependencies": { + "typescript": ">3.6.0", + "webpack": "^5.11.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "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/fork-ts-checker-webpack-plugin/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { + "version": "8.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/memfs": { + "version": "3.5.3", + "dev": true, + "license": "Unlicense", + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { + "version": "7.6.2", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/fs-monkey": { + "version": "1.0.6", + "dev": true, + "license": "Unlicense" + }, + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/giget": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/giget/-/giget-1.2.3.tgz", + "integrity": "sha512-8EHPljDvs7qKykr6uw8b+lqLiUc/vUg+KVTI0uND4s63TdsZM2Xus3mflvF0DDG9SiM4RlCkFGL+7aAjRmV7KA==", + "dev": true, + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.2.3", + "defu": "^6.1.4", + "node-fetch-native": "^1.6.3", + "nypm": "^0.3.8", + "ohash": "^1.1.3", + "pathe": "^1.1.2", + "tar": "^6.2.0" + }, + "bin": { + "giget": "dist/cli.mjs" + } + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "dev": true + }, + "node_modules/glob": { + "version": "10.4.5", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/globals": { + "version": "11.12.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/slash": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/graphql": { + "version": "16.9.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-heading-rank": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-3.0.0.tgz", + "integrity": "sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.0.tgz", + "integrity": "sha512-OGkAxX1Ua3cbcW6EJ5pT/tslVb90uViVkcJ4ZZIMW/R33DX/AkcJcRrPebPwJkHYwlDHXz4aIwvAAaAdtrACFA==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/he": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/headers-polyfill": { + "version": "4.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/html-entities": { + "version": "2.5.2", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/html-loader": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "html-minifier-terser": "^7.2.0", + "parse5": "^7.1.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/html-minifier-terser": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "~5.3.2", + "commander": "^10.0.0", + "entities": "^4.4.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.15.1" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + } + }, + "node_modules/html-minifier-terser/node_modules/commander": { + "version": "10.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/html-webpack-plugin/node_modules/commander": { + "version": "8.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "2.2.0", + "dev": true, + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "dev": true, + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "dev": true, + "license": "MIT", "dependencies": { - "aria-query": "~5.1.3", - "array-includes": "^3.1.8", - "array.prototype.flatmap": "^1.3.2", - "ast-types-flow": "^0.0.8", - "axe-core": "^4.9.1", - "axobject-query": "~3.1.1", - "damerau-levenshtein": "^1.0.8", - "emoji-regex": "^9.2.2", - "es-iterator-helpers": "^1.0.19", - "hasown": "^2.0.2", - "jsx-ast-utils": "^3.3.5", - "language-tags": "^1.0.9", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.8", - "safe-regex-test": "^1.0.3", - "string.prototype.includes": "^2.0.0" + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" }, "engines": { - "node": ">=4.0" + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "dev": true, + "license": "MIT" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } } }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/https-proxy-agent": { + "version": "5.0.1", "dev": true, + "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/husky": { + "version": "9.0.11", + "dev": true, + "license": "MIT", + "bin": { + "husky": "bin.mjs" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.18" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/interpret": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-absolute-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-4.0.1.tgz", + "integrity": "sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/is-arguments": { + "version": "1.1.1", "dev": true, + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": "*" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-react": { - "version": "7.34.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.3.tgz", - "integrity": "sha512-aoW4MV891jkUulwDApQbPYTVZmeuSyFrudpbTAQuj5Fv8VL+o6df2xIGpw8B0hPjAaih1/Fb0om9grCdyFYemA==", + "node_modules/is-array-buffer": { + "version": "3.0.4", "dev": true, + "license": "MIT", "dependencies": { - "array-includes": "^3.1.8", - "array.prototype.findlast": "^1.2.5", - "array.prototype.flatmap": "^1.3.2", - "array.prototype.toreversed": "^1.1.2", - "array.prototype.tosorted": "^1.1.4", - "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.0.19", - "estraverse": "^5.3.0", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.1.2", - "object.entries": "^1.1.8", - "object.fromentries": "^2.0.8", - "object.hasown": "^1.1.4", - "object.values": "^1.2.0", - "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.5", - "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.11" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" }, "engines": { - "node": ">=4" + "node": ">= 0.4" }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", - "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", + "node_modules/is-arrayish": { + "version": "0.2.1", + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.0.0", "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.8", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.8.tgz", - "integrity": "sha512-MIKAclwaDFIiYtVBLzDdm16E+Ty4GwhB6wZlCAG1R3Ur+F9Qbo6PRxpA5DK7XtDgm+WlCoAY2WxAwqhmIDHg6Q==", + "node_modules/is-bigint": { + "version": "1.0.4", "dev": true, - "peerDependencies": { - "eslint": ">=7" + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-react/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/is-binary-path": { + "version": "2.1.0", "dev": true, + "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/eslint-plugin-react/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "node_modules/is-boolean-object": { + "version": "1.1.2", "dev": true, + "license": "MIT", "dependencies": { - "esutils": "^2.0.2" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-react/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/is-callable": { + "version": "1.2.7", "dev": true, + "license": "MIT", "engines": { - "node": ">=4.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-react/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, + "node_modules/is-core-module": { + "version": "2.14.0", + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "hasown": "^2.0.2" }, "engines": { - "node": "*" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.5", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", - "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "node_modules/is-data-view": { + "version": "1.0.1", "dev": true, + "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" + "is-typed-array": "^1.1.13" }, - "bin": { - "resolve": "bin/resolve" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "node_modules/is-date-object": { + "version": "1.0.5", "dev": true, + "license": "MIT", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "node_modules/is-docker": { + "version": "3.0.0", "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/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==", + "node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", "dev": true, + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "call-bind": "^1.0.2" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/is-generator-fn": { + "version": "2.1.0", "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "license": "MIT", + "engines": { + "node": ">=6" } }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/is-generator-function": { + "version": "1.0.10", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint/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==", + "node_modules/is-glob": { + "version": "4.0.3", "dev": true, + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "is-extglob": "^2.1.1" }, "engines": { - "node": ">=7.0.0" + "node": ">=0.10.0" } }, - "node_modules/eslint/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/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "node_modules/is-inside-container": { + "version": "1.0.0", "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, "engines": { - "node": ">=10" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=8" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/is-negative-zero": { + "version": "2.0.3", "dev": true, + "license": "MIT", "engines": { - "node": ">=4.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "node_modules/is-network-error": { + "version": "1.1.0", "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "node_modules/is-node-process": { + "version": "1.2.0", "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, + "license": "MIT" + }, + "node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", "engines": { - "node": ">=10.13.0" + "node": ">=0.12.0" } }, - "node_modules/eslint/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "node_modules/is-number-object": { + "version": "1.0.7", "dev": true, + "license": "MIT", "dependencies": { - "type-fest": "^0.20.2" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "node_modules/is-path-inside": { + "version": "3.0.3", "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -5443,691 +12215,648 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/is-plain-object": { + "version": "2.0.4", "dev": true, + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "isobject": "^3.0.1" }, "engines": { - "node": "*" + "node": ">=0.10.0" } }, - "node_modules/eslint/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.1.4", "dev": true, + "license": "MIT", "dependencies": { - "yocto-queue": "^0.1.0" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "node_modules/is-set": { + "version": "2.0.3", "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint/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==", + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "call-bind": "^1.0.7" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint/node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "node_modules/is-stream": { + "version": "2.0.1", "dev": true, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "node_modules/is-string": { + "version": "1.0.7", "dev": true, + "license": "MIT", "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "node_modules/is-symbol": { + "version": "1.0.4", "dev": true, + "license": "MIT", "dependencies": { - "estraverse": "^5.1.0" + "has-symbols": "^1.0.2" }, "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "node_modules/is-typed-array": { + "version": "1.1.13", "dev": true, + "license": "MIT", "dependencies": { - "estraverse": "^5.2.0" + "which-typed-array": "^1.1.14" }, "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "node_modules/is-weakmap": { + "version": "2.0.2", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.8.x" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "node_modules/is-weakref": { + "version": "1.0.2", "dev": true, + "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" + "call-bind": "^1.0.2" }, "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "node_modules/is-weakset": { + "version": "2.0.3", "dev": true, + "license": "MIT", "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" }, "engines": { - "node": ">= 0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/is-wsl": { + "version": "3.1.0", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.0.0" + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "node_modules/isarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT" }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "node_modules/isobject": { + "version": "3.0.1", "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, + "license": "MIT", "engines": { - "node": ">=8.6.0" + "node": ">=0.10.0" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", "dev": true, + "license": "BSD-3-Clause", "engines": { - "node": ">= 4.9.1" + "node": ">=8" } }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "reusify": "^1.0.4" + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" } }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.6.2", "dev": true, - "dependencies": { - "websocket-driver": ">=0.5.1" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=0.8.0" + "node": ">=10" } }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "node_modules/istanbul-lib-report": { + "version": "3.0.1", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "flat-cache": "^3.0.4" + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=10" } }, - "node_modules/file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", "dev": true, + "license": "MIT", "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" + "semver": "^7.5.3" }, "engines": { - "node": ">= 10.13.0" + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-report/node_modules/semver": { + "version": "7.6.2", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" + "engines": { + "node": ">=10" } }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", "dev": true, + "license": "MIT", "dependencies": { - "to-regex-range": "^5.0.1" + "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" }, "engines": { - "node": ">= 0.8" + "node": ">=10" } }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/istanbul-reports": { + "version": "3.1.7", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "ms": "2.0.0" + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "node_modules/iterator.prototype": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } }, - "node_modules/find-cache-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", - "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "node_modules/jackspeak": { + "version": "3.4.3", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "common-path-prefix": "^3.0.0", - "pkg-dir": "^7.0.0" - }, - "engines": { - "node": ">=14.16" + "@isaacs/cliui": "^8.0.2" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/find-cache-dir/node_modules/find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "node_modules/jest": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/find-cache-dir/node_modules/locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "node_modules/jest-changed-files": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "p-locate": "^6.0.0" + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/find-cache-dir/node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "node_modules/jest-changed-files/node_modules/p-limit": { + "version": "3.1.0", "dev": true, + "license": "MIT", "dependencies": { - "yocto-queue": "^1.0.0" + "yocto-queue": "^0.1.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/find-cache-dir/node_modules/p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "node_modules/jest-changed-files/node_modules/yocto-queue": { + "version": "0.1.0", "dev": true, - "dependencies": { - "p-limit": "^4.0.0" - }, + "license": "MIT", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/find-cache-dir/node_modules/path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "node_modules/jest-circus": { + "version": "29.7.0", "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/find-cache-dir/node_modules/pkg-dir": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", - "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "license": "MIT", "dependencies": { - "find-up": "^6.3.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=14.16" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/jest-circus/node_modules/chalk": { + "version": "4.1.2", "dev": true, + "license": "MIT", "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "node_modules/jest-circus/node_modules/color-convert": { + "version": "2.0.1", "dev": true, + "license": "MIT", "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "color-name": "~1.1.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=7.0.0" } }, - "node_modules/flat-cache/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/jest-circus/node_modules/color-name": { + "version": "1.1.4", "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } + "license": "MIT" }, - "node_modules/flat-cache/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "node_modules/jest-circus/node_modules/p-limit": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" }, "engines": { - "node": "*" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/flat-cache/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/jest-circus/node_modules/slash": { + "version": "3.0.0", "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "license": "MIT", "engines": { - "node": "*" + "node": ">=8" } }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", + "node_modules/jest-circus/node_modules/supports-color": { + "version": "7.2.0", "dev": true, + "license": "MIT", "dependencies": { - "glob": "^7.1.3" + "has-flag": "^4.0.0" }, - "bin": { - "rimraf": "bin.js" + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/node_modules/yocto-queue": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "node_modules/jest-cli": { + "version": "29.7.0", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, "engines": { - "node": ">=4.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" }, "peerDependenciesMeta": { - "debug": { + "node-notifier": { "optional": true } } }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "node_modules/jest-cli/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "license": "MIT", "dependencies": { - "is-callable": "^1.1.3" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/foreground-child": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", - "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "node_modules/jest-cli/node_modules/chalk": { + "version": "4.1.2", "dev": true, + "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=14" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "node_modules/jest-cli/node_modules/color-convert": { + "version": "2.0.1", "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, "engines": { - "node": ">=14" + "node": ">=7.0.0" + } + }, + "node_modules/jest-cli/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-cli/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": ">=8" } }, - "node_modules/fork-ts-checker-webpack-plugin": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-9.0.2.tgz", - "integrity": "sha512-Uochze2R8peoN1XqlSi/rGUkDQpRogtLFocP9+PGu68zk1BDAKXfdeCdyVZpgTk8V8WFVQXdEz426VKjXLO1Gg==", + "node_modules/jest-config": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.16.7", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "cosmiconfig": "^8.2.0", + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", "deepmerge": "^4.2.2", - "fs-extra": "^10.0.0", - "memfs": "^3.4.1", - "minimatch": "^3.0.4", - "node-abort-controller": "^3.0.1", - "schema-utils": "^3.1.1", - "semver": "^7.3.5", - "tapable": "^2.2.1" + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": ">=12.13.0", - "yarn": ">=1.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { - "typescript": ">3.6.0", - "webpack": "^5.11.0" + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/ansi-styles": { + "node_modules/jest-config/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, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -6138,21 +12867,19 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/brace-expansion": { + "node_modules/jest-config/node_modules/brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { + "node_modules/jest-config/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -6164,11 +12891,10 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-convert": { + "node_modules/jest-config/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, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -6176,55 +12902,34 @@ "node": ">=7.0.0" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-name": { + "node_modules/jest-config/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 + "dev": true, + "license": "MIT" }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "node_modules/jest-config/node_modules/glob": { + "version": "7.2.3", "dev": true, + "license": "ISC", "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">=14" + "node": "*" }, "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/memfs": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", - "dev": true, - "dependencies": { - "fs-monkey": "^1.0.4" - }, - "engines": { - "node": ">= 4.0.0" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/minimatch": { + "node_modules/jest-config/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -6232,23 +12937,18 @@ "node": "*" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "node_modules/jest-config/node_modules/slash": { + "version": "3.0.0", "dev": true, - "bin": { - "semver": "bin/semver.js" - }, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/supports-color": { + "node_modules/jest-config/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, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -6256,1122 +12956,1024 @@ "node": ">=8" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "node_modules/jest-diff": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { - "node": ">=12" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/fs-monkey": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", - "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==", - "dev": true - }, - "node_modules/fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "node": ">=8" + }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "node_modules/jest-diff/node_modules/color-convert": { + "version": "2.0.1", "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "node_modules/jest-diff/node_modules/color-name": { + "version": "1.1.4", "dev": true, - "engines": { - "node": ">=6.9.0" - } + "license": "MIT" }, - "node_modules/get-east-asian-width": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", - "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "node_modules/jest-diff/node_modules/supports-color": { + "version": "7.2.0", "dev": true, - "engines": { - "node": ">=18" + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=8" } }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "node_modules/jest-docblock": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "detect-newline": "^3.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "node_modules/jest-each": { + "version": "29.7.0", "dev": true, - "engines": { - "node": ">=10" + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "node_modules/jest-each/node_modules/chalk": { + "version": "4.1.2", "dev": true, + "license": "MIT", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, - "bin": { - "glob": "dist/esm/bin.mjs" + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/jest-each/node_modules/color-convert": { + "version": "2.0.1", "dev": true, + "license": "MIT", "dependencies": { - "is-glob": "^4.0.1" + "color-name": "~1.1.4" }, "engines": { - "node": ">= 6" + "node": ">=7.0.0" } }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true + "node_modules/jest-each/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "node_modules/jest-each/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "node_modules/jest-environment-jsdom": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/jsdom": "^20.0.0", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0", + "jsdom": "^20.0.0" }, "engines": { - "node": ">= 0.4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } } }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "node_modules/jest-environment-node": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/globby/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "node_modules/jest-get-type": { + "version": "29.6.3", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "node_modules/jest-haste-map": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "get-intrinsic": "^1.1.3" + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "dev": true - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "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==", + "node_modules/jest-haste-map/node_modules/jest-worker": { + "version": "29.7.0", "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "node_modules/jest-leak-detector": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0" + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "node_modules/jest-matcher-utils": { + "version": "29.7.0", "dev": true, - "engines": { - "node": ">= 0.4" + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", "dev": true, + "license": "MIT", "dependencies": { - "has-symbols": "^1.0.3" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "node_modules/jest-matcher-utils/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", "dependencies": { - "function-bind": "^1.1.2" + "color-name": "~1.1.4" }, "engines": { - "node": ">= 0.4" + "node": ">=7.0.0" } }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "node_modules/jest-matcher-utils/node_modules/color-name": { + "version": "1.1.4", "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/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==", - "dependencies": { - "react-is": "^16.7.0" - } + "license": "MIT" }, - "node_modules/hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "node_modules/jest-matcher-utils/node_modules/supports-color": { + "version": "7.2.0", "dev": true, + "license": "MIT", "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "node_modules/jest-message-util": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/hpack.js/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/hpack.js/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "license": "MIT", "dependencies": { - "safe-buffer": "~5.1.0" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/html-entities": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", - "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ] - }, - "node_modules/html-loader": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/html-loader/-/html-loader-5.0.0.tgz", - "integrity": "sha512-puaGKdjdVVIFRtgIC2n5dt5bt0N5j6heXlAQZ4Do1MLjHmOT1gCE1Ogg7XZNeJlnOVHHsrZKGs5dfh+XwZ3XPw==", + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", "dev": true, + "license": "MIT", "dependencies": { - "html-minifier-terser": "^7.2.0", - "parse5": "^7.1.2" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 18.12.0" + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/html-minifier-terser": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", - "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", + "node_modules/jest-message-util/node_modules/color-convert": { + "version": "2.0.1", "dev": true, + "license": "MIT", "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "~5.3.2", - "commander": "^10.0.0", - "entities": "^4.4.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.15.1" - }, - "bin": { - "html-minifier-terser": "cli.js" + "color-name": "~1.1.4" }, "engines": { - "node": "^14.13.1 || >=16.0.0" + "node": ">=7.0.0" } }, - "node_modules/html-minifier-terser/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "node_modules/jest-message-util/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-message-util/node_modules/slash": { + "version": "3.0.0", "dev": true, + "license": "MIT", "engines": { - "node": ">=14" + "node": ">=8" } }, - "node_modules/html-webpack-plugin": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", - "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", + "node_modules/jest-message-util/node_modules/supports-color": { + "version": "7.2.0", "dev": true, + "license": "MIT", "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=10.13.0" + "node": ">=8" + } + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" }, "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.20.0" + "jest-resolve": "*" }, "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { + "jest-resolve": { "optional": true } } }, - "node_modules/html-webpack-plugin/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "node_modules/jest-regex-util": { + "version": "29.6.3", "dev": true, + "license": "MIT", "engines": { - "node": ">= 12" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "node_modules/jest-resolve": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" }, "engines": { - "node": ">=12" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], + "license": "MIT", "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/htmlparser2/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "node_modules/jest-resolve/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", - "dev": true - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "node_modules/jest-resolve/node_modules/chalk": { + "version": "4.1.2", "dev": true, + "license": "MIT", "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 0.8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", - "dev": true - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "node_modules/jest-resolve/node_modules/color-convert": { + "version": "2.0.1", "dev": true, + "license": "MIT", "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" + "color-name": "~1.1.4" }, "engines": { - "node": ">=8.0.0" + "node": ">=7.0.0" } }, - "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "node_modules/jest-resolve/node_modules/color-name": { + "version": "1.1.4", "dev": true, - "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, + "license": "MIT" + }, + "node_modules/jest-resolve/node_modules/slash": { + "version": "3.0.0", + "dev": true, + "license": "MIT", "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } + "node": ">=8" } }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "node_modules/jest-resolve/node_modules/supports-color": { + "version": "7.2.0", "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { - "node": ">=10.17.0" + "node": ">=8" } }, - "node_modules/husky": { - "version": "9.0.11", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", - "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", + "node_modules/jest-runner": { + "version": "29.7.0", "dev": true, - "bin": { - "husky": "bin.mjs" + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" }, "engines": { - "node": ">=18" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/typicode" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/hyperdyperid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", - "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "node_modules/jest-runner/node_modules/chalk": { + "version": "4.1.2", "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, "engines": { - "node": ">=10.18" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/jest-runner/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", "dev": true, + "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "node_modules/jest-runner/node_modules/color-convert": { + "version": "2.0.1", "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "license": "MIT", "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "color-name": "~1.1.4" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=7.0.0" } }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "node_modules/jest-runner/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-runner/node_modules/jest-worker": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, "engines": { - "node": ">=4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/import-local": { + "node_modules/jest-runner/node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, + "license": "MIT", "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "node_modules/jest-runner/node_modules/source-map-support": { + "version": "0.5.13", "dev": true, - "engines": { - "node": ">=0.8.19" + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "node_modules/jest-runner/node_modules/yocto-queue": { + "version": "0.1.0", "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "node_modules/jest-runtime": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" }, "engines": { - "node": ">= 0.4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "node_modules/jest-runtime/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">=10.13.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/ipaddr.js": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", - "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "node_modules/jest-runtime/node_modules/brace-expansion": { + "version": "1.1.11", "dev": true, - "engines": { - "node": ">= 10" + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "node_modules/jest-runtime/node_modules/chalk": { + "version": "4.1.2", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "node_modules/jest-runtime/node_modules/color-convert": { + "version": "2.0.1", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" + "color-name": "~1.1.4" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=7.0.0" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + "node_modules/jest-runtime/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" }, - "node_modules/is-async-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", - "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "node_modules/jest-runtime/node_modules/glob": { + "version": "7.2.3", "dev": true, + "license": "ISC", "dependencies": { - "has-tostringtag": "^1.0.0" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">= 0.4" + "node": "*" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "node_modules/jest-runtime/node_modules/minimatch": { + "version": "3.1.2", "dev": true, + "license": "ISC", "dependencies": { - "has-bigints": "^1.0.1" + "brace-expansion": "^1.1.7" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "*" } }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "node_modules/jest-runtime/node_modules/slash": { + "version": "3.0.0", "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "node_modules/jest-runtime/node_modules/strip-bom": { + "version": "4.0.0", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, + "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "node_modules/jest-runtime/node_modules/supports-color": { + "version": "7.2.0", "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", - "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", + "license": "MIT", "dependencies": { - "hasown": "^2.0.2" + "has-flag": "^4.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "node_modules/jest-snapshot": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "is-typed-array": "^1.1.13" + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "node_modules/jest-snapshot/node_modules/chalk": { + "version": "4.1.2", "dev": true, - "bin": { - "is-docker": "cli.js" + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "node_modules/jest-snapshot/node_modules/color-convert": { + "version": "2.0.1", "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, "engines": { - "node": ">=0.10.0" + "node": ">=7.0.0" } }, - "node_modules/is-finalizationregistry": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", - "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "node_modules/jest-snapshot/node_modules/color-name": { + "version": "1.1.4", "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "MIT" }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.6.2", "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "node_modules/jest-snapshot/node_modules/supports-color": { + "version": "7.2.0", "dev": true, + "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "node_modules/jest-util": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "is-extglob": "^2.1.1" + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-inside-container": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "node_modules/jest-util/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "license": "MIT", "dependencies": { - "is-docker": "^3.0.0" - }, - "bin": { - "is-inside-container": "cli.js" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=14.16" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/is-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", - "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", "dev": true, - "engines": { - "node": ">= 0.4" + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/is-network-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", - "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", + "node_modules/jest-util/node_modules/color-convert": { + "version": "2.0.1", "dev": true, - "engines": { - "node": ">=16" + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=7.0.0" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/jest-util/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-util/node_modules/supports-color": { + "version": "7.2.0", "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { - "node": ">=0.12.0" + "node": ">=8" } }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "node_modules/jest-validate": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -7379,66 +13981,73 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.1.2", "dev": true, + "license": "MIT", "dependencies": { - "isobject": "^3.0.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "node_modules/jest-validate/node_modules/color-convert": { + "version": "2.0.1", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "color-name": "~1.1.4" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=7.0.0" } }, - "node_modules/is-set": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", - "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "node_modules/jest-validate/node_modules/color-name": { + "version": "1.1.4", "dev": true, - "engines": { - "node": ">= 0.4" + "license": "MIT" + }, + "node_modules/jest-validate/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=8" } }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "node_modules/jest-watcher": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7" + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "node_modules/jest-watcher/node_modules/ansi-escapes": { + "version": "4.3.2", "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, "engines": { "node": ">=8" }, @@ -7446,190 +14055,259 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "node_modules/jest-watcher/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "node_modules/jest-watcher/node_modules/chalk": { + "version": "4.1.2", "dev": true, + "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "node_modules/jest-watcher/node_modules/color-convert": { + "version": "2.0.1", "dev": true, + "license": "MIT", "dependencies": { - "which-typed-array": "^1.1.14" + "color-name": "~1.1.4" }, "engines": { - "node": ">= 0.4" + "node": ">=7.0.0" + } + }, + "node_modules/jest-watcher/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-watcher/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=8" } }, - "node_modules/is-weakmap": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", - "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "node_modules/jest-watcher/node_modules/type-fest": { + "version": "0.21.3", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "node_modules/jest-worker": { + "version": "27.5.1", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 10.13.0" } }, - "node_modules/is-weakset": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", - "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "node_modules/js-tokens": { + "version": "4.0.0", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4" + "argparse": "^2.0.1" }, - "engines": { - "node": ">= 0.4" + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jscodeshift": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.15.2.tgz", + "integrity": "sha512-FquR7Okgmc4Sd0aEDwqho3rEiKR3BdvuG9jfdHjLJ6JQoWSMpavug3AoIfnfWhxFlf+5pzQh8qjqz0DWFrNQzA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.0", + "@babel/parser": "^7.23.0", + "@babel/plugin-transform-class-properties": "^7.22.5", + "@babel/plugin-transform-modules-commonjs": "^7.23.0", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.11", + "@babel/plugin-transform-optional-chaining": "^7.23.0", + "@babel/plugin-transform-private-methods": "^7.22.5", + "@babel/preset-flow": "^7.22.15", + "@babel/preset-typescript": "^7.23.0", + "@babel/register": "^7.22.15", + "babel-core": "^7.0.0-bridge.0", + "chalk": "^4.1.2", + "flow-parser": "0.*", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.4", + "neo-async": "^2.5.0", + "node-dir": "^0.1.17", + "recast": "^0.23.3", + "temp": "^0.8.4", + "write-file-atomic": "^2.3.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "bin": { + "jscodeshift": "bin/jscodeshift.js" + }, + "peerDependencies": { + "@babel/preset-env": "^7.1.6" + }, + "peerDependenciesMeta": { + "@babel/preset-env": { + "optional": true + } } }, - "node_modules/is-wsl": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", - "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "node_modules/jscodeshift/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": { - "is-inside-container": "^1.0.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=16" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/iterator.prototype": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", - "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "node_modules/jscodeshift/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "define-properties": "^1.2.1", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "reflect.getprototypeof": "^1.0.4", - "set-function-name": "^2.0.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "node_modules/jscodeshift/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": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "color-name": "~1.1.4" }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" + "engines": { + "node": ">=7.0.0" } }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "node_modules/jscodeshift/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/jscodeshift/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": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">= 10.13.0" + "node": ">=8" } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "node_modules/jscodeshift/node_modules/write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "dev": true, "dependencies": { - "argparse": "^2.0.1" + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "node_modules/jsdom": { + "version": "20.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "abab": "^2.0.6", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.4.2", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.11.0", + "xml-name-validator": "^4.0.0" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } } }, "node_modules/jsesc": { "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -7639,32 +14317,27 @@ }, "node_modules/json-buffer": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -7674,9 +14347,8 @@ }, "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, + "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, @@ -7686,9 +14358,8 @@ }, "node_modules/jsx-ast-utils": { "version": "3.3.5", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", - "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", "dev": true, + "license": "MIT", "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", @@ -7701,33 +14372,37 @@ }, "node_modules/keyv": { "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } }, "node_modules/kind-of": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/kleur": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/language-subtag-registry": { "version": "0.3.23", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", - "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", - "dev": true + "dev": true, + "license": "CC0-1.0" }, "node_modules/language-tags": { "version": "1.0.9", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", - "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", "dev": true, + "license": "MIT", "dependencies": { "language-subtag-registry": "^0.3.20" }, @@ -7737,19 +14412,25 @@ }, "node_modules/launch-editor": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.0.tgz", - "integrity": "sha512-vJranOAJrI/llyWGRQqiDM+adrw+k83fvmmx3+nV47g3+36xM15jE+zyZ6Ffel02+xSvuM0b2GDRosXZkbb6wA==", "dev": true, + "license": "MIT", "dependencies": { "picocolors": "^1.0.0", "shell-quote": "^1.8.1" } }, + "node_modules/leven": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/levn": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -7760,9 +14441,8 @@ }, "node_modules/lilconfig": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", "dev": true, + "license": "MIT", "engines": { "node": ">=14" }, @@ -7772,14 +14452,12 @@ }, "node_modules/lines-and-columns": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + "license": "MIT" }, "node_modules/lint-staged": { "version": "15.2.7", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.7.tgz", - "integrity": "sha512-+FdVbbCZ+yoh7E/RosSdqKJyUM2OEjTciH0TFNkawKgvFp1zbGlEC39RADg+xKBG1R4mhoH2j85myBQZ5wR+lw==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "~5.3.0", "commander": "~12.1.0", @@ -7804,9 +14482,8 @@ }, "node_modules/lint-staged/node_modules/chalk": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, + "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -7816,18 +14493,16 @@ }, "node_modules/lint-staged/node_modules/commander": { "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/lint-staged/node_modules/execa": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", @@ -7848,9 +14523,8 @@ }, "node_modules/lint-staged/node_modules/get-stream": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, + "license": "MIT", "engines": { "node": ">=16" }, @@ -7860,18 +14534,16 @@ }, "node_modules/lint-staged/node_modules/human-signals": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=16.17.0" } }, "node_modules/lint-staged/node_modules/is-stream": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -7881,9 +14553,8 @@ }, "node_modules/lint-staged/node_modules/mimic-fn": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -7893,9 +14564,8 @@ }, "node_modules/lint-staged/node_modules/npm-run-path": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^4.0.0" }, @@ -7908,9 +14578,8 @@ }, "node_modules/lint-staged/node_modules/onetime": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^4.0.0" }, @@ -7923,9 +14592,8 @@ }, "node_modules/lint-staged/node_modules/path-key": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -7935,9 +14603,8 @@ }, "node_modules/lint-staged/node_modules/signal-exit": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, + "license": "ISC", "engines": { "node": ">=14" }, @@ -7947,9 +14614,8 @@ }, "node_modules/lint-staged/node_modules/strip-final-newline": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -7959,9 +14625,8 @@ }, "node_modules/lint-staged/node_modules/yaml": { "version": "2.4.5", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", - "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", "dev": true, + "license": "ISC", "bin": { "yaml": "bin.mjs" }, @@ -7971,9 +14636,8 @@ }, "node_modules/listr2": { "version": "8.2.3", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.3.tgz", - "integrity": "sha512-Lllokma2mtoniUOS94CcOErHWAug5iu7HOmDrvWgpw8jyQH2fomgB+7lZS4HWZxytUuQwkGOwe49FvwVaA85Xw==", "dev": true, + "license": "MIT", "dependencies": { "cli-truncate": "^4.0.0", "colorette": "^2.0.20", @@ -7988,9 +14652,228 @@ }, "node_modules/listr2/node_modules/ansi-regex": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/strip-ansi": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/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/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/log-symbols/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/log-symbols/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/log-symbols/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/log-update": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^6.2.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^7.0.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.0.1", + "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -7998,11 +14881,10 @@ "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/listr2/node_modules/ansi-styles": { + "node_modules/log-update/node_modules/ansi-styles": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -8010,23 +14892,44 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/listr2/node_modules/emoji-regex": { + "node_modules/log-update/node_modules/emoji-regex": { "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", - "dev": true + "dev": true, + "license": "MIT" }, - "node_modules/listr2/node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "dev": true + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/listr2/node_modules/string-width": { + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", @@ -8039,11 +14942,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/listr2/node_modules/strip-ansi": { + "node_modules/log-update/node_modules/strip-ansi": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -8054,11 +14956,10 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/listr2/node_modules/wrap-ansi": { + "node_modules/log-update/node_modules/wrap-ansi": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", - "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", @@ -8071,508 +14972,760 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "node_modules/loose-envify": { + "version": "1.4.0", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/make-dir": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, "engines": { - "node": ">=6.11.5" + "node": ">=6" } }, - "node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "node_modules/make-dir/node_modules/semver": { + "version": "5.7.2", "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" + "tmpl": "1.0.5" + } + }, + "node_modules/map-or-similar": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/map-or-similar/-/map-or-similar-1.5.0.tgz", + "integrity": "sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==", + "dev": true + }, + "node_modules/markdown-to-jsx": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.4.7.tgz", + "integrity": "sha512-0+ls1IQZdU6cwM1yu0ZjjiVWYtkbExSyUIFU2ZeDIFuZM1W42Mh4OlJ4nb4apX4H8smxDHRdFaoIVJGwfv5hkg==", + "dev": true, + "engines": { + "node": ">= 10" }, + "peerDependencies": { + "react": ">= 0.14.0" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "dev": true, + "license": "MIT", "engines": { - "node": ">=8.9.0" + "node": ">= 0.6" } }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/memfs": { + "version": "4.9.3", "dev": true, + "license": "Apache-2.0", "dependencies": { - "p-locate": "^4.1.0" + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.1.2", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" }, "engines": { - "node": ">=8" + "node": ">= 4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "node_modules/memoizerific": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/memoizerific/-/memoizerific-1.11.3.tgz", + "integrity": "sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==", + "dev": true, + "dependencies": { + "map-or-similar": "^1.5.0" + } }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true + "node_modules/merge-descriptors": { + "version": "1.0.1", + "dev": true, + "license": "MIT" }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "node_modules/merge-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT" }, - "node_modules/log-update": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", - "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", + "node_modules/merge2": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", "dev": true, + "license": "MIT", "dependencies": { - "ansi-escapes": "^6.2.0", - "cli-cursor": "^4.0.0", - "slice-ansi": "^7.0.0", - "strip-ansi": "^7.1.0", - "wrap-ansi": "^9.0.0" + "braces": "^3.0.3", + "picomatch": "^2.3.1" }, "engines": { - "node": ">=18" + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "9.0.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/log-update/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "node_modules/minimist": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "dev": true, - "engines": { - "node": ">=12" + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "engines": { + "node": ">= 8" } }, - "node_modules/log-update/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, - "engines": { - "node": ">=12" + "dependencies": { + "yallist": "^4.0.0" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "engines": { + "node": ">=8" } }, - "node_modules/log-update/node_modules/emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "node_modules/log-update/node_modules/is-fullwidth-code-point": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", - "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, - "dependencies": { - "get-east-asian-width": "^1.0.0" + "bin": { + "mkdirp": "bin/cmd.js" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=10" } }, - "node_modules/log-update/node_modules/slice-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", - "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "node_modules/mlly": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.1.tgz", + "integrity": "sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==", "dev": true, "dependencies": { - "ansi-styles": "^6.2.1", - "is-fullwidth-code-point": "^5.0.0" + "acorn": "^8.11.3", + "pathe": "^1.1.2", + "pkg-types": "^1.1.1", + "ufo": "^1.5.3" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/msw": { + "version": "2.3.1", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@bundled-es-modules/cookie": "^2.0.0", + "@bundled-es-modules/statuses": "^1.0.1", + "@inquirer/confirm": "^3.0.0", + "@mswjs/cookies": "^1.1.0", + "@mswjs/interceptors": "^0.29.0", + "@open-draft/until": "^2.1.0", + "@types/cookie": "^0.6.0", + "@types/statuses": "^2.0.4", + "chalk": "^4.1.2", + "graphql": "^16.8.1", + "headers-polyfill": "^4.0.2", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.2", + "path-to-regexp": "^6.2.0", + "strict-event-emitter": "^0.5.1", + "type-fest": "^4.9.0", + "yargs": "^17.7.2" + }, + "bin": { + "msw": "cli/index.js" }, "engines": { "node": ">=18" }, "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" + "url": "https://github.com/sponsors/mswjs" + }, + "peerDependencies": { + "typescript": ">= 4.7.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/log-update/node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "node_modules/msw/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "license": "MIT", "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=18" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/log-update/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "node_modules/msw/node_modules/chalk": { + "version": "4.1.2", "dev": true, + "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/log-update/node_modules/wrap-ansi": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", - "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "node_modules/msw/node_modules/color-convert": { + "version": "2.0.1", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" + "color-name": "~1.1.4" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">=7.0.0" } }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "node_modules/msw/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/msw/node_modules/path-to-regexp": { + "version": "6.2.2", + "dev": true, + "license": "MIT" + }, + "node_modules/msw/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" + "has-flag": "^4.0.0" }, - "bin": { - "loose-envify": "cli.js" + "engines": { + "node": ">=8" } }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "node_modules/msw/node_modules/type-fest": { + "version": "4.21.0", "dev": true, - "dependencies": { - "tslib": "^2.0.3" + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "node_modules/multicast-dns": { + "version": "7.2.5", "dev": true, + "license": "MIT", "dependencies": { - "yallist": "^3.0.2" + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" } }, - "node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "node_modules/mute-stream": { + "version": "1.0.0", "dev": true, - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, + "license": "ISC", "engines": { - "node": ">=6" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/make-dir/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "bin": { - "semver": "bin/semver" + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "node_modules/natural-compare": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.3", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } }, - "node_modules/memfs": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.9.3.tgz", - "integrity": "sha512-bsYSSnirtYTWi1+OPMFb0M048evMKyUYe0EbtuGQgq6BVQM1g1W8/KIUJCCvjgI/El0j6Q4WsmMiBwLUBSw8LA==", + "node_modules/neo-async": { + "version": "2.6.2", + "dev": true, + "license": "MIT" + }, + "node_modules/no-case": { + "version": "3.0.4", "dev": true, + "license": "MIT", "dependencies": { - "@jsonjoy.com/json-pack": "^1.0.3", - "@jsonjoy.com/util": "^1.1.2", - "tree-dump": "^1.0.1", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">= 4.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" + "lower-case": "^2.0.2", + "tslib": "^2.0.3" } }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "node_modules/node-abort-controller": { + "version": "3.1.1", + "dev": true, + "license": "MIT" }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "node_modules/node-dir": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", + "integrity": "sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==", "dev": true, + "dependencies": { + "minimatch": "^3.0.2" + }, "engines": { - "node": ">= 8" + "node": ">= 0.10.5" } }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "node_modules/node-dir/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "engines": { - "node": ">= 0.6" + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "node_modules/node-dir/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=8.6" + "node": "*" } }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "node_modules/node-fetch-native": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.4.tgz", + "integrity": "sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==", + "dev": true + }, + "node_modules/node-forge": { + "version": "1.3.1", "dev": true, - "bin": { - "mime": "cli.js" - }, + "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { - "node": ">=4" + "node": ">= 6.13.0" } }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "node_modules/node-int64": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.14", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">=0.10.0" } }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "node_modules/npm-run-path": { + "version": "4.0.1", "dev": true, + "license": "MIT", "dependencies": { - "mime-db": "1.52.0" + "path-key": "^3.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "node_modules/nth-check": { + "version": "2.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/nwsapi": { + "version": "2.2.12", "dev": true, + "license": "MIT" + }, + "node_modules/nypm": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.3.9.tgz", + "integrity": "sha512-BI2SdqqTHg2d4wJh8P9A1W+bslg33vOE9IZDY6eR2QC+Pu1iNBVZUqczrd43rJb+fMzHU7ltAYKsEFY/kHMFcw==", + "dev": true, + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.2.3", + "execa": "^8.0.1", + "pathe": "^1.1.2", + "pkg-types": "^1.1.1", + "ufo": "^1.5.3" + }, + "bin": { + "nypm": "dist/cli.mjs" + }, "engines": { - "node": ">=6" + "node": "^14.16.0 || >=16.10.0" } }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "node_modules/nypm/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, "dependencies": { - "brace-expansion": "^2.0.1" + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=16.17" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "node_modules/nypm/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, + "engines": { + "node": ">=16" + }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "node_modules/nypm/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=16.17.0" } }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "node_modules/nypm/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, - "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, - "bin": { - "multicast-dns": "cli.js" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "node_modules/nypm/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "node_modules/nypm/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/node-abort-controller": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", - "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", - "dev": true - }, - "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "node_modules/nypm/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, "engines": { - "node": ">= 6.13.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "node_modules/nypm/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "node_modules/nypm/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, "engines": { - "node": ">=8" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "node_modules/nypm/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, - "dependencies": { - "boolbase": "^1.0.0" + "engines": { + "node": ">=12" }, "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/object-inspect": { "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -8582,9 +15735,8 @@ }, "node_modules/object-is": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", - "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1" @@ -8598,18 +15750,16 @@ }, "node_modules/object-keys": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/object.assign": { "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -8625,9 +15775,8 @@ }, "node_modules/object.entries": { "version": "1.1.8", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", - "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -8639,9 +15788,8 @@ }, "node_modules/object.fromentries": { "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -8657,9 +15805,8 @@ }, "node_modules/object.groupby": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -8671,9 +15818,8 @@ }, "node_modules/object.hasown": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", - "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", "dev": true, + "license": "MIT", "dependencies": { "define-properties": "^1.2.1", "es-abstract": "^1.23.2", @@ -8688,9 +15834,8 @@ }, "node_modules/object.values": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -8703,17 +15848,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/objectorarray": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/objectorarray/-/objectorarray-1.0.5.tgz", + "integrity": "sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg==", + "dev": true + }, "node_modules/obuf": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true, + "license": "MIT" + }, + "node_modules/ohash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.3.tgz", + "integrity": "sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==", "dev": true }, "node_modules/on-finished": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, + "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -8723,27 +15878,24 @@ }, "node_modules/on-headers": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/onetime": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -8756,9 +15908,8 @@ }, "node_modules/open": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", - "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", "dev": true, + "license": "MIT", "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", @@ -8774,9 +15925,8 @@ }, "node_modules/optionator": { "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -8789,11 +15939,124 @@ "node": ">= 0.8.0" } }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/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/ora/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/ora/node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/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/ora/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/ora/node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/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/outvariant": { + "version": "1.4.3", + "dev": true, + "license": "MIT" + }, "node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -8806,9 +16069,8 @@ }, "node_modules/p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -8818,9 +16080,8 @@ }, "node_modules/p-retry": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.0.tgz", - "integrity": "sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA==", "dev": true, + "license": "MIT", "dependencies": { "@types/retry": "0.12.2", "is-network-error": "^1.0.0", @@ -8835,24 +16096,21 @@ }, "node_modules/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, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/package-json-from-dist": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", - "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", - "dev": true + "dev": true, + "license": "BlueOak-1.0.0" }, "node_modules/param-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", "dev": true, + "license": "MIT", "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" @@ -8860,8 +16118,7 @@ }, "node_modules/parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -8871,8 +16128,7 @@ }, "node_modules/parse-json": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -8888,9 +16144,8 @@ }, "node_modules/parse5": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", "dev": true, + "license": "MIT", "dependencies": { "entities": "^4.4.0" }, @@ -8900,60 +16155,59 @@ }, "node_modules/parseurl": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/pascal-case": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", "dev": true, + "license": "MIT", "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" } }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true + }, "node_modules/path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-parse": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "license": "MIT" }, "node_modules/path-scurry": { "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -8967,34 +16221,44 @@ }, "node_modules/path-scurry/node_modules/lru-cache": { "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/path-to-regexp": { "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", "dev": true }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, "engines": { - "node": ">=8" + "node": "*" } }, "node_modules/picocolors": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -9004,9 +16268,8 @@ }, "node_modules/pidtree": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", - "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", "dev": true, + "license": "MIT", "bin": { "pidtree": "bin/pidtree.js" }, @@ -9016,18 +16279,24 @@ }, "node_modules/pify": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/pirates": { + "version": "4.0.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, "node_modules/pkg-dir": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^4.0.0" }, @@ -9035,29 +16304,155 @@ "node": ">=8" } }, + "node_modules/pkg-types": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.3.tgz", + "integrity": "sha512-+JrgthZG6m3ckicaOB74TwQ+tBWsFl3qVQg7mN8ulwSOElJ7gBhKzj2VkCPnZ4NlF6kEquYU+RIYNVAvzd54UA==", + "dev": true, + "dependencies": { + "confbox": "^0.1.7", + "mlly": "^1.7.1", + "pathe": "^1.1.2" + } + }, + "node_modules/polished": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/polished/-/polished-4.3.1.tgz", + "integrity": "sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.17.8" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/possible-typed-array-names": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } }, + "node_modules/postcss": { + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", + "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", + "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/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, + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", + "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, "node_modules/prelude-ls": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } }, "node_modules/prettier": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", - "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, @@ -9070,25 +16465,72 @@ }, "node_modules/pretty-error": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", "dev": true, + "license": "MIT", "dependencies": { "lodash": "^4.17.20", "renderkid": "^3.0.0" } }, + "node_modules/pretty-format": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "18.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/prompts": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } }, "node_modules/prop-types": { "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "dev": true, + "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -9097,9 +16539,8 @@ }, "node_modules/proxy-addr": { "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, + "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -9110,27 +16551,44 @@ }, "node_modules/proxy-addr/node_modules/ipaddr.js": { "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } }, + "node_modules/psl": { + "version": "1.9.0", + "dev": true, + "license": "MIT" + }, "node_modules/punycode": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/pure-rand": { + "version": "6.1.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, "node_modules/qs": { "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.4" }, @@ -9141,10 +16599,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "dev": true, + "license": "MIT" + }, "node_modules/queue-microtask": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { @@ -9159,31 +16620,29 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/randombytes": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } }, "node_modules/range-parser": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/raw-body": { "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dev": true, + "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -9196,17 +16655,15 @@ }, "node_modules/raw-body/node_modules/bytes": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/react": { "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" }, @@ -9214,10 +16671,79 @@ "node": ">=0.10.0" } }, + "node_modules/react-colorful": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-5.6.1.tgz", + "integrity": "sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==", + "dev": true, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/react-confetti": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/react-confetti/-/react-confetti-6.1.0.tgz", + "integrity": "sha512-7Ypx4vz0+g8ECVxr88W9zhcQpbeujJAVqL14ZnXJ3I23mOI9/oBVTQ3dkJhUmB0D6XOtCZEM6N0Gm9PMngkORw==", + "dev": true, + "dependencies": { + "tween-functions": "^1.2.0" + }, + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "react": "^16.3.0 || ^17.0.1 || ^18.0.0" + } + }, + "node_modules/react-docgen": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-7.0.3.tgz", + "integrity": "sha512-i8aF1nyKInZnANZ4uZrH49qn1paRgBZ7wZiCNBMnenlPzEv0mRl+ShpTVEI6wZNl8sSc79xZkivtgLKQArcanQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.18.9", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9", + "@types/babel__core": "^7.18.0", + "@types/babel__traverse": "^7.18.0", + "@types/doctrine": "^0.0.9", + "@types/resolve": "^1.20.2", + "doctrine": "^3.0.0", + "resolve": "^1.22.1", + "strip-indent": "^4.0.0" + }, + "engines": { + "node": ">=16.14.0" + } + }, + "node_modules/react-docgen-typescript": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/react-docgen-typescript/-/react-docgen-typescript-2.2.2.tgz", + "integrity": "sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg==", + "dev": true, + "peerDependencies": { + "typescript": ">= 4.3.x" + } + }, + "node_modules/react-docgen/node_modules/strip-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", + "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/react-dom": { "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -9226,16 +16752,74 @@ "react": "^18.3.1" } }, + "node_modules/react-element-to-jsx-string": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/react-element-to-jsx-string/-/react-element-to-jsx-string-15.0.0.tgz", + "integrity": "sha512-UDg4lXB6BzlobN60P8fHWVPX3Kyw8ORrTeBtClmIlGdkOOE+GYQSFvmEU5iLLpwp/6v42DINwNcwOhOLfQ//FQ==", + "dev": true, + "dependencies": { + "@base2/pretty-print-object": "1.0.1", + "is-plain-object": "5.0.0", + "react-is": "18.1.0" + }, + "peerDependencies": { + "react": "^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0", + "react-dom": "^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0" + } + }, + "node_modules/react-element-to-jsx-string/node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-element-to-jsx-string/node_modules/react-is": { + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz", + "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==", + "dev": true + }, "node_modules/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==" + "license": "MIT" + }, + "node_modules/react-router": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.24.1.tgz", + "integrity": "sha512-PTXFXGK2pyXpHzVo3rR9H7ip4lSPZZc0bHG5CARmj65fTT6qG7sTngmb6lcYu1gf3y/8KxORoy9yn59pGpCnpg==", + "dependencies": { + "@remix-run/router": "1.17.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.24.1.tgz", + "integrity": "sha512-U19KtXqooqw967Vw0Qcn5cOvrX5Ejo9ORmOtJMzYWtCT4/WOfFLIZGGsVLxcd9UkBO0mSTZtXqhZBsWlHr7+Sg==", + "dependencies": { + "@remix-run/router": "1.17.1", + "react-router": "6.24.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } }, "node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -9247,9 +16831,8 @@ }, "node_modules/readdirp": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, + "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -9257,11 +16840,26 @@ "node": ">=8.10.0" } }, + "node_modules/recast": { + "version": "0.23.9", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.9.tgz", + "integrity": "sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==", + "dev": true, + "dependencies": { + "ast-types": "^0.16.1", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tiny-invariant": "^1.3.3", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">= 4" + } + }, "node_modules/rechoir": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "dev": true, + "license": "MIT", "dependencies": { "resolve": "^1.20.0" }, @@ -9269,11 +16867,22 @@ "node": ">= 10.13.0" } }, + "node_modules/redent": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", - "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -9292,15 +16901,13 @@ }, "node_modules/regenerate": { "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/regenerate-unicode-properties": { "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", "dev": true, + "license": "MIT", "dependencies": { "regenerate": "^1.4.2" }, @@ -9310,23 +16917,20 @@ }, "node_modules/regenerator-runtime": { "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + "license": "MIT" }, "node_modules/regenerator-transform": { "version": "0.15.2", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", - "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/runtime": "^7.8.4" } }, "node_modules/regexp.prototype.flags": { "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.6", "define-properties": "^1.2.1", @@ -9342,9 +16946,8 @@ }, "node_modules/regexpu-core": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", @@ -9359,9 +16962,8 @@ }, "node_modules/regjsparser": { "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "jsesc": "~0.5.0" }, @@ -9371,27 +16973,58 @@ }, "node_modules/regjsparser/node_modules/jsesc": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", "dev": true, "bin": { "jsesc": "bin/jsesc" } }, + "node_modules/rehype-external-links": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/rehype-external-links/-/rehype-external-links-3.0.0.tgz", + "integrity": "sha512-yp+e5N9V3C6bwBeAC4n796kc86M4gJCdlVhiMTxIrJG5UHDMh+PJANf9heqORJbt1nrCbDwIlAZKjANIaVBbvw==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-is-element": "^3.0.0", + "is-absolute-url": "^4.0.0", + "space-separated-tokens": "^2.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-slug": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/rehype-slug/-/rehype-slug-6.0.0.tgz", + "integrity": "sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0", + "github-slugger": "^2.0.0", + "hast-util-heading-rank": "^3.0.0", + "hast-util-to-string": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/relateurl": { "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } }, "node_modules/renderkid": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", "dev": true, + "license": "MIT", "dependencies": { "css-select": "^4.1.3", "dom-converter": "^0.2.0", @@ -9400,25 +17033,39 @@ "strip-ansi": "^6.0.1" } }, + "node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/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==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true, + "engines": { + "node": ">=0.10.5" + } + }, "node_modules/requires-port": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/resolve": { "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -9433,9 +17080,8 @@ }, "node_modules/resolve-cwd": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, + "license": "MIT", "dependencies": { "resolve-from": "^5.0.0" }, @@ -9445,18 +17091,24 @@ }, "node_modules/resolve-from": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/restore-cursor": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", "dev": true, + "license": "MIT", "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -9470,18 +17122,16 @@ }, "node_modules/retry": { "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/reusify": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -9489,15 +17139,13 @@ }, "node_modules/rfdc": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/rimraf": { "version": "5.0.9", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.9.tgz", - "integrity": "sha512-3i7b8OcswU6CpU8Ej89quJD4O98id7TtVM5U4Mybh84zQXdrFmDLouWBEEaD/QfO3gDDfH+AGFCGsR7kngzQnA==", "dev": true, + "license": "ISC", "dependencies": { "glob": "^10.3.7" }, @@ -9513,9 +17161,8 @@ }, "node_modules/run-applescript": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", - "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -9525,8 +17172,6 @@ }, "node_modules/run-parallel": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { @@ -9542,15 +17187,15 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, "node_modules/safe-array-concat": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "get-intrinsic": "^1.2.4", @@ -9566,14 +17211,11 @@ }, "node_modules/safe-array-concat/node_modules/isarray": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { @@ -9588,13 +17230,13 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/safe-regex-test": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -9609,23 +17251,31 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/saxes": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } }, "node_modules/scheduler": { "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" } }, "node_modules/schema-utils": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -9641,15 +17291,13 @@ }, "node_modules/select-hose": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/selfsigned": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", "dev": true, + "license": "MIT", "dependencies": { "@types/node-forge": "^1.3.0", "node-forge": "^1" @@ -9660,18 +17308,16 @@ }, "node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/send": { "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dev": true, + "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -9693,39 +17339,34 @@ }, "node_modules/send/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/send/node_modules/ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/serialize-javascript": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/serve-index": { "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", "dev": true, + "license": "MIT", "dependencies": { "accepts": "~1.3.4", "batch": "0.6.1", @@ -9741,27 +17382,24 @@ }, "node_modules/serve-index/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/serve-index/node_modules/depd": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/serve-index/node_modules/http-errors": { "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", "dev": true, + "license": "MIT", "dependencies": { "depd": "~1.1.2", "inherits": "2.0.3", @@ -9774,36 +17412,31 @@ }, "node_modules/serve-index/node_modules/inherits": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/serve-index/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/serve-index/node_modules/setprototypeof": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/serve-index/node_modules/statuses": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/serve-static": { "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dev": true, + "license": "MIT", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -9816,9 +17449,8 @@ }, "node_modules/set-function-length": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -9833,9 +17465,8 @@ }, "node_modules/set-function-name": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -9848,15 +17479,13 @@ }, "node_modules/setprototypeof": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/shallow-clone": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "dev": true, + "license": "MIT", "dependencies": { "kind-of": "^6.0.2" }, @@ -9866,9 +17495,8 @@ }, "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -9878,27 +17506,24 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/shell-quote": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/side-channel": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -9906,171 +17531,479 @@ "object-inspect": "^1.13.1" }, "engines": { - "node": ">= 0.4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "dev": true, + "license": "ISC" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/slash": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "dev": true, + "license": "MIT", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/spdy": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "internal-slot": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/storybook": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.2.2.tgz", + "integrity": "sha512-xDT9gyzAEFQNeK7P+Mj/8bNzN+fbm6/4D6ihdSzmczayjydpNjMs74HDHMY6S4Bfu6tRVyEK2ALPGnr6ZVofBA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.24.4", + "@babel/types": "^7.24.0", + "@storybook/codemod": "8.2.2", + "@storybook/core": "8.2.2", + "@types/semver": "^7.3.4", + "@yarnpkg/fslib": "2.10.3", + "@yarnpkg/libzip": "2.3.0", + "chalk": "^4.1.0", + "commander": "^6.2.1", + "cross-spawn": "^7.0.3", + "detect-indent": "^6.1.0", + "envinfo": "^7.7.3", + "execa": "^5.0.0", + "fd-package-json": "^1.2.0", + "find-up": "^5.0.0", + "fs-extra": "^11.1.0", + "giget": "^1.0.0", + "globby": "^14.0.1", + "jscodeshift": "^0.15.1", + "leven": "^3.1.0", + "ora": "^5.4.1", + "prettier": "^3.1.1", + "prompts": "^2.4.0", + "semver": "^7.3.7", + "strip-json-comments": "^3.0.1", + "tempy": "^3.1.0", + "tiny-invariant": "^1.3.1", + "ts-dedent": "^2.0.0" + }, + "bin": { + "getstorybook": "bin/index.cjs", + "sb": "bin/index.cjs", + "storybook": "bin/index.cjs" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/storybook/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/storybook/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/storybook/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/storybook/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/storybook/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/storybook/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "node_modules/storybook/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, "engines": { - "node": ">=6" + "node": ">=14.14" } }, - "node_modules/slice-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "node_modules/storybook/node_modules/globby": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", "dev": true, "dependencies": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" }, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "node_modules/storybook/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "node_modules/storybook/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "node_modules/storybook/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "node_modules/storybook/node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "node_modules/storybook/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "node_modules/storybook/node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true, - "dependencies": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, "engines": { - "node": ">=6.0.0" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "node_modules/storybook/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": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "node_modules/storybook/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "engines": { - "node": ">= 0.8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/stop-iteration-iterator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", - "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "node_modules/strict-event-emitter": { + "version": "0.5.1", "dev": true, - "dependencies": { - "internal-slot": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } + "license": "MIT" }, "node_modules/string_decoder": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } }, "node_modules/string-argv": { "version": "0.3.2", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", - "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.6.19" } }, + "node_modules/string-length": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/string-width": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, + "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -10086,9 +18019,8 @@ "node_modules/string-width-cjs": { "name": "string-width", "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -10100,15 +18032,13 @@ }, "node_modules/string-width-cjs/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/string-width/node_modules/ansi-regex": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -10118,9 +18048,8 @@ }, "node_modules/string-width/node_modules/strip-ansi": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -10133,9 +18062,8 @@ }, "node_modules/string.prototype.includes": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.0.tgz", - "integrity": "sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==", "dev": true, + "license": "MIT", "dependencies": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" @@ -10143,9 +18071,8 @@ }, "node_modules/string.prototype.matchall": { "version": "4.0.11", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", - "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -10169,9 +18096,8 @@ }, "node_modules/string.prototype.trim": { "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -10179,143 +18105,336 @@ "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-loader": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", + "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", + "dev": true, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/stylis": { + "version": "4.2.0", + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "node_modules/swc-loader": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/swc-loader/-/swc-loader-0.2.6.tgz", + "integrity": "sha512-9Zi9UP2YmDpgmQVbyOPJClY0dwf58JDyDMQ7uRc4krmc72twNI2fvlBWHLqVekBpPc7h5NJkGVT1zNDxFrqhvg==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" + "@swc/counter": "^0.1.3" }, + "peerDependencies": { + "@swc/core": "^1.2.147", + "webpack": ">=2" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.2.1", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6" } }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", "dev": true, "dependencies": { - "ansi-regex": "^5.0.1" + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, "engines": { "node": ">=8" } }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/telejson": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/telejson/-/telejson-7.2.0.tgz", + "integrity": "sha512-1QTEcJkJEhc8OnStBx/ILRu5J2p0GjvWsBx56bmZRqnrkdBMUe+nX92jxV+p3dB4CP6PZCdJMQJwCggkNBMzkQ==", "dev": true, "dependencies": { - "ansi-regex": "^5.0.1" + "memoizerific": "^1.11.3" + } + }, + "node_modules/temp": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.4.tgz", + "integrity": "sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==", + "dev": true, + "dependencies": { + "rimraf": "~2.6.2" }, "engines": { - "node": ">=8" + "node": ">=6.0.0" } }, - "node_modules/strip-bom": { + "node_modules/temp-dir": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", + "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", "dev": true, "engines": { - "node": ">=4" + "node": ">=14.16" } }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "node_modules/temp/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "engines": { - "node": ">=6" + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "node_modules/temp/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, "engines": { - "node": ">=8" + "node": "*" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/stylis": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + "node_modules/temp/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/temp/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/tempy": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-3.1.0.tgz", + "integrity": "sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==", + "dev": true, + "dependencies": { + "is-stream": "^3.0.0", + "temp-dir": "^3.0.0", + "type-fest": "^2.12.2", + "unique-string": "^3.0.0" }, "engines": { - "node": ">=10" + "node": ">=14.16" }, "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "node_modules/tempy/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, "engines": { - "node": ">= 0.4" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "node_modules/tempy/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "dev": true, "engines": { - "node": ">=6" + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/terser": { "version": "5.31.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.2.tgz", - "integrity": "sha512-LGyRZVFm/QElZHy/CPr/O4eNZOZIzsrQ92y4v9UJe/pFJjypje2yI3C2FmPtvUEnhadlSbmG2nXtdcjHOjCfxw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -10331,9 +18450,8 @@ }, "node_modules/terser-webpack-plugin": { "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", @@ -10363,17 +18481,67 @@ } } }, + "node_modules/test-exclude": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/text-table": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/thingies": { "version": "1.21.0", - "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", - "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", "dev": true, + "license": "Unlicense", "engines": { "node": ">=10.18" }, @@ -10383,23 +18551,40 @@ }, "node_modules/thunky": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", "dev": true }, + "node_modules/tinyspy": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/to-fast-properties": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -10409,18 +18594,49 @@ }, "node_modules/toidentifier": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.6" } }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/tr46": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/tree-dump": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", - "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=10.0" }, @@ -10434,9 +18650,8 @@ }, "node_modules/ts-api-utils": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=16" }, @@ -10444,11 +18659,19 @@ "typescript": ">=4.2.0" } }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "dev": true, + "engines": { + "node": ">=6.10" + } + }, "node_modules/ts-loader": { "version": "9.5.1", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", - "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "enhanced-resolve": "^5.0.0", @@ -10466,9 +18689,8 @@ }, "node_modules/ts-loader/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, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -10481,9 +18703,8 @@ }, "node_modules/ts-loader/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -10497,9 +18718,8 @@ }, "node_modules/ts-loader/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, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -10509,15 +18729,13 @@ }, "node_modules/ts-loader/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 + "dev": true, + "license": "MIT" }, "node_modules/ts-loader/node_modules/semver": { "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -10527,18 +18745,16 @@ }, "node_modules/ts-loader/node_modules/source-map": { "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">= 8" } }, "node_modules/ts-loader/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, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -10548,9 +18764,8 @@ }, "node_modules/tsconfig-paths": { "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, + "license": "MIT", "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", @@ -10560,9 +18775,8 @@ }, "node_modules/tsconfig-paths/node_modules/json5": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, + "license": "MIT", "dependencies": { "minimist": "^1.2.0" }, @@ -10572,15 +18786,40 @@ }, "node_modules/tslib": { "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true, + "license": "0BSD" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tween-functions": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tween-functions/-/tween-functions-1.2.0.tgz", + "integrity": "sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA==", "dev": true }, "node_modules/type-check": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -10588,11 +18827,18 @@ "node": ">= 0.8.0" } }, + "node_modules/type-detect": { + "version": "4.0.8", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/type-fest": { "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -10602,9 +18848,8 @@ }, "node_modules/type-is": { "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -10615,9 +18860,8 @@ }, "node_modules/typed-array-buffer": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -10629,9 +18873,8 @@ }, "node_modules/typed-array-byte-length": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -10648,9 +18891,8 @@ }, "node_modules/typed-array-byte-offset": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", "dev": true, + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -10668,9 +18910,8 @@ }, "node_modules/typed-array-length": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -10688,9 +18929,8 @@ }, "node_modules/typescript": { "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -10699,11 +18939,16 @@ "node": ">=14.17" } }, + "node_modules/ufo": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", + "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", + "dev": true + }, "node_modules/unbox-primitive": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -10716,24 +18961,21 @@ }, "node_modules/undici-types": { "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/unicode-match-property-ecmascript": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, + "license": "MIT", "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" @@ -10744,44 +18986,122 @@ }, "node_modules/unicode-match-property-value-ecmascript": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/unicode-property-aliases-ecmascript": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unique-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", + "dev": true, + "dependencies": { + "crypto-random-string": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/universalify": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.0.0" } }, "node_modules/unpipe": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, + "node_modules/unplugin": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.11.0.tgz", + "integrity": "sha512-3r7VWZ/webh0SGgJScpWl2/MRCZK5d3ZYFcNaeci/GQ7Teop7zf0Nl2pUuz7G21BwPd9pcUPOC5KmJ2L3WgC5g==", + "dev": true, + "dependencies": { + "acorn": "^8.11.3", + "chokidar": "^3.6.0", + "webpack-sources": "^3.2.3", + "webpack-virtual-modules": "^0.6.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "dev": true, "funding": [ { @@ -10797,6 +19117,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "escalade": "^3.1.2", "picocolors": "^1.0.1" @@ -10810,57 +19131,141 @@ }, "node_modules/uri-js": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } }, + "node_modules/url": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", + "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", + "dev": true, + "dependencies": { + "punycode": "^1.4.1", + "qs": "^6.11.2" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "dev": true, + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true + }, + "node_modules/url/node_modules/qs": { + "version": "6.12.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.3.tgz", + "integrity": "sha512-AWJm14H1vVaO/iNZ4/hO+HyaTehuy9nRqVdkTqlJt0HWvBiBIEXFmb4C0DGeYo3Xes9rrEW+TxHsaigCbN5ICQ==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/utila": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/utils-merge": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4.0" } }, "node_modules/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, + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, "node_modules/vary": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, + "node_modules/w3c-xmlserializer": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/walk-up-path": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-3.0.1.tgz", + "integrity": "sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==", + "dev": true + }, + "node_modules/walker": { + "version": "1.0.8", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, "node_modules/watchpack": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", "dev": true, + "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -10871,18 +19276,33 @@ }, "node_modules/wbuf": { "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "dev": true, + "license": "MIT", "dependencies": { "minimalistic-assert": "^1.0.0" } }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, "node_modules/webpack": { "version": "5.92.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz", - "integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==", "dev": true, + "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", @@ -10927,9 +19347,8 @@ }, "node_modules/webpack-cli": { "version": "5.1.4", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", - "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, + "license": "MIT", "dependencies": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^2.1.1", @@ -10972,18 +19391,16 @@ }, "node_modules/webpack-cli/node_modules/commander": { "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", "dev": true, + "license": "MIT", "engines": { "node": ">=14" } }, "node_modules/webpack-cli/node_modules/webpack-merge": { "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", "dev": true, + "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", "flat": "^5.0.2", @@ -10995,9 +19412,8 @@ }, "node_modules/webpack-dev-middleware": { "version": "7.2.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.2.1.tgz", - "integrity": "sha512-hRLz+jPQXo999Nx9fXVdKlg/aehsw1ajA9skAneGmT03xwmyuhvF93p6HUKKbWhXdcERtGTzUCtIQr+2IQegrA==", "dev": true, + "license": "MIT", "dependencies": { "colorette": "^2.0.10", "memfs": "^4.6.0", @@ -11024,9 +19440,8 @@ }, "node_modules/webpack-dev-middleware/node_modules/ajv": { "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", @@ -11040,9 +19455,8 @@ }, "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -11052,15 +19466,13 @@ }, "node_modules/webpack-dev-middleware/node_modules/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==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/webpack-dev-middleware/node_modules/schema-utils": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -11077,9 +19489,8 @@ }, "node_modules/webpack-dev-server": { "version": "5.0.4", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.0.4.tgz", - "integrity": "sha512-dljXhUgx3HqKP2d8J/fUMvhxGhzjeNVarDLcbO/EWMSgRizDkxHQDZQaLFL5VJY9tRBj2Gz+rvCEYYvhbqPHNA==", "dev": true, + "license": "MIT", "dependencies": { "@types/bonjour": "^3.5.13", "@types/connect-history-api-fallback": "^1.5.4", @@ -11136,9 +19547,8 @@ }, "node_modules/webpack-dev-server/node_modules/ajv": { "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", @@ -11152,9 +19562,8 @@ }, "node_modules/webpack-dev-server/node_modules/ajv-keywords": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -11164,15 +19573,13 @@ }, "node_modules/webpack-dev-server/node_modules/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==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/webpack-dev-server/node_modules/schema-utils": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -11187,11 +19594,21 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/webpack-hot-middleware": { + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.26.1.tgz", + "integrity": "sha512-khZGfAeJx6I8K9zKohEWWYN6KDlVw2DHownoe+6Vtwj1LP9WFgegXnVMSkZ/dBEBtXFwrkkydsaPFlB7f8wU2A==", + "dev": true, + "dependencies": { + "ansi-html-community": "0.0.8", + "html-entities": "^2.1.0", + "strip-ansi": "^6.0.0" + } + }, "node_modules/webpack-merge": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", - "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", "dev": true, + "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", "flat": "^5.0.2", @@ -11203,18 +19620,22 @@ }, "node_modules/webpack-sources": { "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.13.0" } }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "dev": true + }, "node_modules/websocket-driver": { "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", @@ -11226,18 +19647,58 @@ }, "node_modules/websocket-extensions": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=0.8.0" } }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "11.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -11250,9 +19711,8 @@ }, "node_modules/which-boxed-primitive": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, + "license": "MIT", "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -11266,9 +19726,8 @@ }, "node_modules/which-builtin-type": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", - "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", "dev": true, + "license": "MIT", "dependencies": { "function.prototype.name": "^1.1.5", "has-tostringtag": "^1.0.0", @@ -11292,15 +19751,13 @@ }, "node_modules/which-builtin-type/node_modules/isarray": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/which-collection": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", - "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, + "license": "MIT", "dependencies": { "is-map": "^2.0.3", "is-set": "^2.0.3", @@ -11316,9 +19773,8 @@ }, "node_modules/which-typed-array": { "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", "dev": true, + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -11335,24 +19791,21 @@ }, "node_modules/wildcard": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/word-wrap": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/wrap-ansi": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -11368,9 +19821,8 @@ "node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -11385,9 +19837,8 @@ }, "node_modules/wrap-ansi-cjs/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, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -11400,9 +19851,8 @@ }, "node_modules/wrap-ansi-cjs/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, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -11412,21 +19862,18 @@ }, "node_modules/wrap-ansi-cjs/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 + "dev": true, + "license": "MIT" }, "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/wrap-ansi-cjs/node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -11438,9 +19885,8 @@ }, "node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -11450,9 +19896,8 @@ }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -11462,9 +19907,8 @@ }, "node_modules/wrap-ansi/node_modules/strip-ansi": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -11477,15 +19921,25 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "dev": true, + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } }, "node_modules/ws": { "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -11502,31 +19956,103 @@ } } }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/y18n": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, "node_modules/yallist": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yaml": { "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", "engines": { "node": ">= 6" } }, + "node_modules/yargs": { + "version": "17.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/yocto-queue": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", - "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/frontend/package.json b/frontend/package.json index 7a9c58cb..2d7a5c6e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -7,16 +7,21 @@ "start": "webpack serve --config webpack.config.dev.js", "build-dev": "webpack --config webpack.config.dev.js", "build-prod": "webpack --config webpack.config.prod.js", + "test": "jest --watch", "lint": "npx eslint --ext .ts,.tsx .", - "prepare": "cd .. && husky frontend/.husky" + "prepare": "cd .. && husky frontend/.husky", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "@emotion/react": "^11.11.4", + "@tanstack/react-query": "^5.51.1", "react": "^18.3.1", - "react-dom": "^18.3.1" + "react-dom": "^18.3.1", + "react-router-dom": "^6.24.1" }, "devDependencies": { "@babel/cli": "^7.24.8", @@ -24,6 +29,21 @@ "@babel/preset-env": "^7.24.8", "@babel/preset-react": "^7.24.7", "@babel/preset-typescript": "^7.24.7", + "@chromatic-com/storybook": "^1.6.1", + "@storybook/addon-essentials": "^8.2.2", + "@storybook/addon-interactions": "^8.2.2", + "@storybook/addon-links": "^8.2.2", + "@storybook/addon-onboarding": "^8.2.2", + "@storybook/addon-webpack5-compiler-swc": "^1.0.4", + "@storybook/blocks": "^8.2.2", + "@storybook/react": "^8.2.2", + "@storybook/react-webpack5": "^8.2.2", + "@storybook/test": "^8.2.2", + "@tanstack/eslint-plugin-query": "^5.51.1", + "@testing-library/jest-dom": "^6.4.6", + "@testing-library/react": "^16.0.0", + "@testing-library/user-event": "^14.5.2", + "@types/jest": "^29.5.12", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@typescript-eslint/eslint-plugin": "^7.16.0", @@ -37,13 +57,18 @@ "eslint-plugin-react": "^7.34.3", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.8", + "eslint-plugin-storybook": "^0.8.0", "file-loader": "^6.2.0", "fork-ts-checker-webpack-plugin": "^9.0.2", "html-loader": "^5.0.0", "html-webpack-plugin": "^5.6.0", "husky": "^9.0.11", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", "lint-staged": "^15.2.7", + "msw": "^2.3.1", "prettier": "^3.3.2", + "storybook": "^8.2.2", "ts-loader": "^9.5.1", "typescript": "^5.5.3", "webpack": "^5.92.1", From 1f3eab2eee0dc8e83859168682097525390dd510 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sun, 14 Jul 2024 15:09:56 +0900 Subject: [PATCH 0010/1013] =?UTF-8?q?chore:=20=EC=9D=98=EC=A1=B4=EC=84=B1?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20eslint=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EC=84=A4=EC=A0=95=20#2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.eslintrc.json | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json index 5e8fcd5d..3377bc15 100644 --- a/frontend/.eslintrc.json +++ b/frontend/.eslintrc.json @@ -10,6 +10,8 @@ "plugin:react-hooks/recommended", "plugin:import/recommended", "plugin:jsx-a11y/recommended", + "plugin:storybook/recommended", + "plugin:@tanstack/eslint-plugin-query/recommended", "prettier" ], "parser": "@typescript-eslint/parser", @@ -18,11 +20,22 @@ "sourceType": "module" }, "plugins": ["react", "@typescript-eslint", "react-refresh"], + "ignorePatterns": ["webpack.config.common.js", "webpack.config.dev.js", "webpack.config.prod.js"], "rules": { "react/react-in-jsx-scope": "off", "@typescript-eslint/no-unused-vars": "warn", - "react/function-component-definition": ["error", { "namedComponents": "arrow-function" }], - "react-refresh/only-export-components": ["warn", { "allowConstantExport": true }], + "react/function-component-definition": [ + "error", + { + "namedComponents": "arrow-function" + } + ], + "react-refresh/only-export-components": [ + "warn", + { + "allowConstantExport": true + } + ], "import/no-unresolved": "off", "import/order": [ "error", From ff697325530843e1815135c3b8b2779d4974adab Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sun, 14 Jul 2024 15:11:07 +0900 Subject: [PATCH 0011/1013] =?UTF-8?q?chore:=20jest=20=EB=B0=8F=20RTL=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=ED=99=98=EA=B2=BD=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20#2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/jest.config.json | 7 +++++++ frontend/jest.setup.ts | 1 + 2 files changed, 8 insertions(+) create mode 100644 frontend/jest.config.json create mode 100644 frontend/jest.setup.ts diff --git a/frontend/jest.config.json b/frontend/jest.config.json new file mode 100644 index 00000000..831d9051 --- /dev/null +++ b/frontend/jest.config.json @@ -0,0 +1,7 @@ +{ + "testEnvironment": "jsdom", + "moduleNameMapper": { + "^@/(.*)$": "/src/$1" + }, + "setupFilesAfterEnv": ["/jest.setup.ts"] +} diff --git a/frontend/jest.setup.ts b/frontend/jest.setup.ts new file mode 100644 index 00000000..7b0828bf --- /dev/null +++ b/frontend/jest.setup.ts @@ -0,0 +1 @@ +import '@testing-library/jest-dom'; From c42d839768957592d4c81b2f1d3f0bc881e95ff2 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sun, 14 Jul 2024 15:13:13 +0900 Subject: [PATCH 0012/1013] =?UTF-8?q?chore:=20storybook=20=EC=8B=A4?= =?UTF-8?q?=ED=96=89=20=ED=99=98=EA=B2=BD=20=EC=84=A4=EC=A0=95=20#2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.gitignore | 2 ++ frontend/.storybook/main.ts | 45 ++++++++++++++++++++++++++++++++++ frontend/.storybook/preview.ts | 14 +++++++++++ frontend/{ => src}/custom.d.ts | 0 frontend/tsconfig.json | 3 ++- 5 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 frontend/.storybook/main.ts create mode 100644 frontend/.storybook/preview.ts rename frontend/{ => src}/custom.d.ts (100%) diff --git a/frontend/.gitignore b/frontend/.gitignore index 95fbd9d2..a78f7809 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -26,3 +26,5 @@ dist-ssr .env .env.development .env.production + +*storybook.log \ No newline at end of file diff --git a/frontend/.storybook/main.ts b/frontend/.storybook/main.ts new file mode 100644 index 00000000..13e1b260 --- /dev/null +++ b/frontend/.storybook/main.ts @@ -0,0 +1,45 @@ +import type { StorybookConfig } from '@storybook/react-webpack5'; +import path from 'path'; +import { Configuration } from 'webpack'; + +const config: StorybookConfig = { + stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], + addons: [ + '@storybook/addon-webpack5-compiler-swc', + '@storybook/addon-onboarding', + '@storybook/addon-links', + '@storybook/addon-essentials', + '@chromatic-com/storybook', + '@storybook/addon-interactions', + ], + framework: { + name: '@storybook/react-webpack5', + options: { + builder: { + useSWC: true, + }, + }, + }, + swc: () => ({ + jsc: { + transform: { + react: { + runtime: 'automatic', + }, + }, + }, + }), + webpackFinal: async (config: Configuration) => { + const { resolve } = config; + + if (resolve) { + resolve.alias = { + ...resolve.alias, + '@': path.resolve(__dirname, '../src'), + }; + } + + return config; + }, +}; +export default config; diff --git a/frontend/.storybook/preview.ts b/frontend/.storybook/preview.ts new file mode 100644 index 00000000..adcda96b --- /dev/null +++ b/frontend/.storybook/preview.ts @@ -0,0 +1,14 @@ +import type { Preview } from '@storybook/react'; + +const preview: Preview = { + parameters: { + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i, + }, + }, + }, +}; + +export default preview; diff --git a/frontend/custom.d.ts b/frontend/src/custom.d.ts similarity index 100% rename from frontend/custom.d.ts rename to frontend/src/custom.d.ts diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index 72d246b0..499f49e7 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -16,5 +16,6 @@ "@/*": ["src/*"] } }, - "include": ["src"] + "include": ["src"], + "exclude": ["node_modules"] } From 0cb1da3675c449b69d66cbd6156911b4d53edafb Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sun, 14 Jul 2024 15:31:37 +0900 Subject: [PATCH 0013/1013] =?UTF-8?q?chore:=20msw=20=EC=8B=A4=ED=96=89=20?= =?UTF-8?q?=ED=99=98=EA=B2=BD=20=EC=84=A4=EC=A0=95=20#2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/package.json | 7 +- frontend/public/mockServiceWorker.js | 284 +++++++++++++++++++++++++++ frontend/src/index.tsx | 14 +- frontend/src/mocks/browser.ts | 5 + frontend/src/mocks/data/.gitkeep | 0 frontend/src/mocks/handlers/index.ts | 1 + frontend/src/mocks/server.ts | 17 ++ 7 files changed, 326 insertions(+), 2 deletions(-) create mode 100644 frontend/public/mockServiceWorker.js create mode 100644 frontend/src/mocks/browser.ts create mode 100644 frontend/src/mocks/data/.gitkeep create mode 100644 frontend/src/mocks/handlers/index.ts create mode 100644 frontend/src/mocks/server.ts diff --git a/frontend/package.json b/frontend/package.json index 2d7a5c6e..2a941e6f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -81,5 +81,10 @@ "eslint --fix", "prettier --write" ] + }, + "msw": { + "workerDirectory": [ + "public" + ] } -} +} \ No newline at end of file diff --git a/frontend/public/mockServiceWorker.js b/frontend/public/mockServiceWorker.js new file mode 100644 index 00000000..24fe3a25 --- /dev/null +++ b/frontend/public/mockServiceWorker.js @@ -0,0 +1,284 @@ +/* eslint-disable */ +/* tslint:disable */ + +/** + * Mock Service Worker. + * @see https://github.com/mswjs/msw + * - Please do NOT modify this file. + * - Please do NOT serve this file on production. + */ + +const PACKAGE_VERSION = '2.3.1' +const INTEGRITY_CHECKSUM = '26357c79639bfa20d64c0efca2a87423' +const IS_MOCKED_RESPONSE = Symbol('isMockedResponse') +const activeClientIds = new Set() + +self.addEventListener('install', function () { + self.skipWaiting() +}) + +self.addEventListener('activate', function (event) { + event.waitUntil(self.clients.claim()) +}) + +self.addEventListener('message', async function (event) { + const clientId = event.source.id + + if (!clientId || !self.clients) { + return + } + + const client = await self.clients.get(clientId) + + if (!client) { + return + } + + const allClients = await self.clients.matchAll({ + type: 'window', + }) + + switch (event.data) { + case 'KEEPALIVE_REQUEST': { + sendToClient(client, { + type: 'KEEPALIVE_RESPONSE', + }) + break + } + + case 'INTEGRITY_CHECK_REQUEST': { + sendToClient(client, { + type: 'INTEGRITY_CHECK_RESPONSE', + payload: { + packageVersion: PACKAGE_VERSION, + checksum: INTEGRITY_CHECKSUM, + }, + }) + break + } + + case 'MOCK_ACTIVATE': { + activeClientIds.add(clientId) + + sendToClient(client, { + type: 'MOCKING_ENABLED', + payload: true, + }) + break + } + + case 'MOCK_DEACTIVATE': { + activeClientIds.delete(clientId) + break + } + + case 'CLIENT_CLOSED': { + activeClientIds.delete(clientId) + + const remainingClients = allClients.filter((client) => { + return client.id !== clientId + }) + + // Unregister itself when there are no more clients + if (remainingClients.length === 0) { + self.registration.unregister() + } + + break + } + } +}) + +self.addEventListener('fetch', function (event) { + const { request } = event + + // Bypass navigation requests. + if (request.mode === 'navigate') { + return + } + + // Opening the DevTools triggers the "only-if-cached" request + // that cannot be handled by the worker. Bypass such requests. + if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { + return + } + + // Bypass all requests when there are no active clients. + // Prevents the self-unregistered worked from handling requests + // after it's been deleted (still remains active until the next reload). + if (activeClientIds.size === 0) { + return + } + + // Generate unique request ID. + const requestId = crypto.randomUUID() + event.respondWith(handleRequest(event, requestId)) +}) + +async function handleRequest(event, requestId) { + const client = await resolveMainClient(event) + const response = await getResponse(event, client, requestId) + + // Send back the response clone for the "response:*" life-cycle events. + // Ensure MSW is active and ready to handle the message, otherwise + // this message will pend indefinitely. + if (client && activeClientIds.has(client.id)) { + ;(async function () { + const responseClone = response.clone() + + sendToClient( + client, + { + type: 'RESPONSE', + payload: { + requestId, + isMockedResponse: IS_MOCKED_RESPONSE in response, + type: responseClone.type, + status: responseClone.status, + statusText: responseClone.statusText, + body: responseClone.body, + headers: Object.fromEntries(responseClone.headers.entries()), + }, + }, + [responseClone.body], + ) + })() + } + + return response +} + +// Resolve the main client for the given event. +// Client that issues a request doesn't necessarily equal the client +// that registered the worker. It's with the latter the worker should +// communicate with during the response resolving phase. +async function resolveMainClient(event) { + const client = await self.clients.get(event.clientId) + + if (client?.frameType === 'top-level') { + return client + } + + const allClients = await self.clients.matchAll({ + type: 'window', + }) + + return allClients + .filter((client) => { + // Get only those clients that are currently visible. + return client.visibilityState === 'visible' + }) + .find((client) => { + // Find the client ID that's recorded in the + // set of clients that have registered the worker. + return activeClientIds.has(client.id) + }) +} + +async function getResponse(event, client, requestId) { + const { request } = event + + // Clone the request because it might've been already used + // (i.e. its body has been read and sent to the client). + const requestClone = request.clone() + + function passthrough() { + const headers = Object.fromEntries(requestClone.headers.entries()) + + // Remove internal MSW request header so the passthrough request + // complies with any potential CORS preflight checks on the server. + // Some servers forbid unknown request headers. + delete headers['x-msw-intention'] + + return fetch(requestClone, { headers }) + } + + // Bypass mocking when the client is not active. + if (!client) { + return passthrough() + } + + // Bypass initial page load requests (i.e. static assets). + // The absence of the immediate/parent client in the map of the active clients + // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet + // and is not ready to handle requests. + if (!activeClientIds.has(client.id)) { + return passthrough() + } + + // Notify the client that a request has been intercepted. + const requestBuffer = await request.arrayBuffer() + const clientMessage = await sendToClient( + client, + { + type: 'REQUEST', + payload: { + id: requestId, + url: request.url, + mode: request.mode, + method: request.method, + headers: Object.fromEntries(request.headers.entries()), + cache: request.cache, + credentials: request.credentials, + destination: request.destination, + integrity: request.integrity, + redirect: request.redirect, + referrer: request.referrer, + referrerPolicy: request.referrerPolicy, + body: requestBuffer, + keepalive: request.keepalive, + }, + }, + [requestBuffer], + ) + + switch (clientMessage.type) { + case 'MOCK_RESPONSE': { + return respondWithMock(clientMessage.data) + } + + case 'PASSTHROUGH': { + return passthrough() + } + } + + return passthrough() +} + +function sendToClient(client, message, transferrables = []) { + return new Promise((resolve, reject) => { + const channel = new MessageChannel() + + channel.port1.onmessage = (event) => { + if (event.data && event.data.error) { + return reject(event.data.error) + } + + resolve(event.data) + } + + client.postMessage( + message, + [channel.port2].concat(transferrables.filter(Boolean)), + ) + }) +} + +async function respondWithMock(response) { + // Setting response status code to 0 is a no-op. + // However, when responding with a "Response.error()", the produced Response + // instance will have status code set to 0. Since it's not possible to create + // a Response instance with status code 0, handle that use-case separately. + if (response.status === 0) { + return Response.error() + } + + const mockedResponse = new Response(response.body, response) + + Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { + value: true, + enumerable: true, + }) + + return mockedResponse +} diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 0d3cae1d..4f23d523 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -2,4 +2,16 @@ import ReactDOM from 'react-dom/client'; import App from './App'; -ReactDOM.createRoot(document.getElementById('root')!).render(); +const enableMocking = async () => { + if (process.env.NODE_ENV !== 'development') { + return; + } + + const { worker } = await import('./mocks/browser'); + + return await worker.start(); +}; + +enableMocking().then(() => { + ReactDOM.createRoot(document.getElementById('root')!).render(); +}); diff --git a/frontend/src/mocks/browser.ts b/frontend/src/mocks/browser.ts new file mode 100644 index 00000000..c95883bc --- /dev/null +++ b/frontend/src/mocks/browser.ts @@ -0,0 +1,5 @@ +import { setupWorker } from 'msw/browser'; + +import { handlers } from './handlers'; + +export const worker = setupWorker(...handlers); diff --git a/frontend/src/mocks/data/.gitkeep b/frontend/src/mocks/data/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/mocks/handlers/index.ts b/frontend/src/mocks/handlers/index.ts new file mode 100644 index 00000000..0f3710c6 --- /dev/null +++ b/frontend/src/mocks/handlers/index.ts @@ -0,0 +1 @@ +export const handlers = []; diff --git a/frontend/src/mocks/server.ts b/frontend/src/mocks/server.ts new file mode 100644 index 00000000..8a51966b --- /dev/null +++ b/frontend/src/mocks/server.ts @@ -0,0 +1,17 @@ +import { setupServer } from 'msw/node'; + +import { handlers } from './handlers'; + +export const server = setupServer(...handlers); + +beforeAll(() => { + server.listen({ onUnhandledRequest: 'error' }); +}); + +afterEach(() => { + server.resetHandlers(); +}); + +afterAll(() => { + server.close(); +}); From 4f6689f5e10e3f106ff4ca36b9c074cec3303e87 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sun, 14 Jul 2024 15:45:44 +0900 Subject: [PATCH 0014/1013] =?UTF-8?q?chore:=20webpack=20=ED=99=98=EA=B2=BD?= =?UTF-8?q?=EB=B3=80=EC=88=98=20=EC=84=A4=EC=A0=95=20=EB=B0=8F=20productio?= =?UTF-8?q?n=20=EB=B2=88=EB=93=A4=20=EC=82=AC=EC=9D=B4=EC=A6=88=20?= =?UTF-8?q?=EC=A1=B0=EC=A0=88=20#2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/package-lock.json | 13 +++++++++++++ frontend/package.json | 3 ++- frontend/webpack.config.common.js | 8 ++++++++ frontend/webpack.config.prod.js | 5 +++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index a24ac0bd..5bff2434 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -42,6 +42,7 @@ "@typescript-eslint/parser": "^7.16.0", "babel-loader": "^9.1.3", "core-js": "^3.37.1", + "dotenv": "^16.4.5", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.29.1", @@ -9060,6 +9061,18 @@ "tslib": "^2.0.3" } }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "dev": true, diff --git a/frontend/package.json b/frontend/package.json index 2a941e6f..b25c93bb 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -50,6 +50,7 @@ "@typescript-eslint/parser": "^7.16.0", "babel-loader": "^9.1.3", "core-js": "^3.37.1", + "dotenv": "^16.4.5", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.29.1", @@ -87,4 +88,4 @@ "public" ] } -} \ No newline at end of file +} diff --git a/frontend/webpack.config.common.js b/frontend/webpack.config.common.js index 3ac38adf..80fd2897 100644 --- a/frontend/webpack.config.common.js +++ b/frontend/webpack.config.common.js @@ -1,5 +1,10 @@ const path = require('path'); const HTMLWebpackPlugin = require('html-webpack-plugin'); +const webpack = require('webpack'); +const dotenv = require('dotenv'); + +// this will update the process.env with environment variables in .env file +dotenv.config(); module.exports = { entry: './src/index.tsx', @@ -42,5 +47,8 @@ module.exports = { template: './index.html', // 읽을 파일명 filename: './index.html', // output으로 출력할 파일명 }), + new webpack.DefinePlugin({ + 'process.env': JSON.stringify(process.env), + }), ], }; diff --git a/frontend/webpack.config.prod.js b/frontend/webpack.config.prod.js index 73665a93..09eec58c 100644 --- a/frontend/webpack.config.prod.js +++ b/frontend/webpack.config.prod.js @@ -13,4 +13,9 @@ module.exports = merge(common, { }, ], }, + performance: { + hints: false, + maxEntrypointSize: 512000, + maxAssetSize: 512000, + }, }); From e71c6be838ca32d2fb6c37096109cb5c5b289f36 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sun, 14 Jul 2024 15:56:38 +0900 Subject: [PATCH 0015/1013] =?UTF-8?q?init:=20=EB=94=94=EB=A0=89=ED=86=A0?= =?UTF-8?q?=EB=A6=AC=20=EA=B5=AC=EC=A1=B0=20=EC=84=B8=ED=8C=85=20#2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/.gitkeep | 0 frontend/src/assets/images/.gitkeep | 0 frontend/src/components/.gitkeep | 0 frontend/src/constants/.gitkeep | 0 frontend/src/hooks/.gitkeep | 0 frontend/src/pages/.gitkeep | 0 frontend/src/router/.gitkeep | 0 frontend/src/styles/.gitkeep | 0 frontend/src/types/.gitkeep | 0 frontend/src/utils/.gitkeep | 0 10 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 frontend/src/apis/.gitkeep create mode 100644 frontend/src/assets/images/.gitkeep create mode 100644 frontend/src/components/.gitkeep create mode 100644 frontend/src/constants/.gitkeep create mode 100644 frontend/src/hooks/.gitkeep create mode 100644 frontend/src/pages/.gitkeep create mode 100644 frontend/src/router/.gitkeep create mode 100644 frontend/src/styles/.gitkeep create mode 100644 frontend/src/types/.gitkeep create mode 100644 frontend/src/utils/.gitkeep diff --git a/frontend/src/apis/.gitkeep b/frontend/src/apis/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/assets/images/.gitkeep b/frontend/src/assets/images/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/components/.gitkeep b/frontend/src/components/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/constants/.gitkeep b/frontend/src/constants/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/hooks/.gitkeep b/frontend/src/hooks/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/pages/.gitkeep b/frontend/src/pages/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/router/.gitkeep b/frontend/src/router/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/styles/.gitkeep b/frontend/src/styles/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/types/.gitkeep b/frontend/src/types/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/utils/.gitkeep b/frontend/src/utils/.gitkeep new file mode 100644 index 00000000..e69de29b From 99847b8fb2d17c4821af8c3661ee216601c8c9f2 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Mon, 15 Jul 2024 01:40:43 +0900 Subject: [PATCH 0016/1013] =?UTF-8?q?chore:=20stylelint=EB=A1=9C=20css=20?= =?UTF-8?q?=EC=84=A0=EC=96=B8=20=EC=88=9C=EC=84=9C=20=EC=A0=95=EB=A0=AC=20?= =?UTF-8?q?=EB=B0=8F=20husky=EB=A1=9C=20=EC=84=A4=EC=A0=95=20#2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.eslintrc.json | 1 + frontend/.husky/pre-commit | 2 +- frontend/.stylelintrc.json | 86 +++++ frontend/package-lock.json | 704 +++++++++++++++++++++++++++++++++++++ frontend/package.json | 5 + 5 files changed, 797 insertions(+), 1 deletion(-) create mode 100644 frontend/.stylelintrc.json diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json index 3377bc15..9fbeff47 100644 --- a/frontend/.eslintrc.json +++ b/frontend/.eslintrc.json @@ -24,6 +24,7 @@ "rules": { "react/react-in-jsx-scope": "off", "@typescript-eslint/no-unused-vars": "warn", + "react/no-unknown-property": ["error", { "ignore": ["css"] }], "react/function-component-definition": [ "error", { diff --git a/frontend/.husky/pre-commit b/frontend/.husky/pre-commit index f450749a..5e9988bb 100644 --- a/frontend/.husky/pre-commit +++ b/frontend/.husky/pre-commit @@ -1 +1 @@ -cd frontend && npx lint-staged +cd frontend && npx lint-staged && npm run lint:styled diff --git a/frontend/.stylelintrc.json b/frontend/.stylelintrc.json new file mode 100644 index 00000000..74c4003b --- /dev/null +++ b/frontend/.stylelintrc.json @@ -0,0 +1,86 @@ +{ + "extends": ["stylelint-config-standard"], + "plugins": ["stylelint-order"], + "customSyntax": "postcss-styled-syntax", + "rules": { + "declaration-empty-line-before": [ + "always", + { + "ignore": ["first-nested", "after-comment", "after-declaration", "inside-single-line-block"] + } + ], + "order/order": ["custom-properties", "declarations"], + + "order/properties-order": [ + { + "groupName": "Layout", + "noEmptyLineBetween": true, + "properties": [ + "display", + "visibility", + "overflow", + "float", + "clear", + "position", + "top", + "right", + "bottom", + "left", + "z-index", + "flex-direction", + "justify-content", + "align-items" + ] + }, + { + "groupName": "Box", + "emptyLineBefore": "always", + "noEmptyLineBetween": true, + "properties": [ + "width", + "height", + "margin", + "margin-top", + "margin-right", + "margin-bottom", + "margin-left", + "padding", + "padding-top", + "padding-right", + "padding-bottom", + "padding-left", + "border" + ] + }, + { + "groupName": "Background", + "emptyLineBefore": "always", + "noEmptyLineBetween": true, + "properties": ["background-color"] + }, + { + "groupName": "Font", + "emptyLineBefore": "always", + "noEmptyLineBetween": true, + "properties": [ + "color", + "font-style", + "font-weight", + "font-size", + "line-height", + "letter-spacing", + "text-align", + "text-indent", + "vertical-align", + "white-space" + ] + }, + { + "groupName": "Animation", + "emptyLineBefore": "always", + "noEmptyLineBetween": true, + "properties": ["animation"] + } + ] + } +} diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 5bff2434..b017fb65 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -60,8 +60,12 @@ "jest-environment-jsdom": "^29.7.0", "lint-staged": "^15.2.7", "msw": "^2.3.1", + "postcss-styled-syntax": "^0.6.4", "prettier": "^3.3.2", "storybook": "^8.2.2", + "stylelint": "^16.7.0", + "stylelint-config-standard": "^36.0.1", + "stylelint-order": "^6.0.4", "ts-loader": "^9.5.1", "typescript": "^5.5.3", "webpack": "^5.92.1", @@ -2090,6 +2094,92 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.7.1.tgz", + "integrity": "sha512-2SJS42gxmACHgikc1WGesXLIT8d/q2l0UFM7TaEeIzdFCE/FPMtTiizcPGGJtlPo2xuQzY09OhrLTzRxqJqwGw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^2.4.1" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.4.1.tgz", + "integrity": "sha512-eQ9DIktFJBhGjioABJRtUucoWR2mwllurfnM8LuNGAqX3ViZXaUchqk+1s7jjtkFiT9ySdACsFEA3etErkALUg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + } + }, + "node_modules/@csstools/media-query-list-parser": { + "version": "2.1.13", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.13.tgz", + "integrity": "sha512-XaHr+16KRU9Gf8XLi3q8kDlI18d5vzKSKCY510Vrtc9iNR0NJzbY9hhTmwhzYZj/ZwGL4VmB3TA9hJW0Um2qFA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^2.7.1", + "@csstools/css-tokenizer": "^2.4.1" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.1.1.tgz", + "integrity": "sha512-a7cxGcJ2wIlMFLlh8z2ONm+715QkPHiyJcxwQlKOz/03GPw1COpfhcmC9wm4xlZfp//jWHNNMwzjtqHXVWU9KA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^6.0.13" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "dev": true, @@ -2098,6 +2188,16 @@ "node": ">=10.0.0" } }, + "node_modules/@dual-bundle/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/@emotion/babel-plugin": { "version": "11.11.0", "license": "MIT", @@ -7181,6 +7281,15 @@ "dev": true, "license": "MIT" }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/asynckit": { "version": "0.4.0", "dev": true, @@ -8194,6 +8303,12 @@ "version": "1.1.3", "license": "MIT" }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "dev": true + }, "node_modules/colorette": { "version": "2.0.20", "dev": true, @@ -8500,6 +8615,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/css-functions-list": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.2.tgz", + "integrity": "sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==", + "dev": true, + "engines": { + "node": ">=12 || >=16" + } + }, "node_modules/css-loader": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", @@ -8562,6 +8686,19 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, "node_modules/css-what": { "version": "6.1.0", "dev": true, @@ -9160,6 +9297,15 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/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, + "engines": { + "node": ">=6" + } + }, "node_modules/envinfo": { "version": "7.13.0", "dev": true, @@ -11207,6 +11353,44 @@ "dev": true, "license": "BSD-2-Clause" }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, "node_modules/globals": { "version": "11.12.0", "license": "MIT", @@ -11256,6 +11440,12 @@ "node": ">=8" } }, + "node_modules/globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", + "dev": true + }, "node_modules/gopd": { "version": "1.0.1", "dev": true, @@ -11871,6 +12061,12 @@ "dev": true, "license": "ISC" }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, "node_modules/internal-slot": { "version": "1.0.7", "dev": true, @@ -14407,6 +14603,12 @@ "node": ">=6" } }, + "node_modules/known-css-properties": { + "version": "0.34.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.34.0.tgz", + "integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==", + "dev": true + }, "node_modules/language-subtag-registry": { "version": "0.3.23", "dev": true, @@ -14788,6 +14990,12 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -15083,6 +15291,22 @@ "react": ">= 0.14.0" } }, + "node_modules/mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true + }, "node_modules/media-typer": { "version": "0.3.0", "dev": true, @@ -15118,6 +15342,18 @@ "map-or-similar": "^1.5.0" } }, + "node_modules/meow": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", + "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/merge-descriptors": { "version": "1.0.1", "dev": true, @@ -16435,6 +16671,38 @@ "postcss": "^8.1.0" } }, + "node_modules/postcss-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", + "dev": true + }, + "node_modules/postcss-safe-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.0.tgz", + "integrity": "sha512-ovehqRNVCpuFzbXoTb4qLtyzK3xn3t/CUBxOs8LsnQjQrShaB4lKiHoVqY8ANaC0hBMHq5QVWk77rwGklFUDrg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-safe-parser" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, "node_modules/postcss-selector-parser": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", @@ -16448,6 +16716,30 @@ "node": ">=4" } }, + "node_modules/postcss-sorting": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-8.0.2.tgz", + "integrity": "sha512-M9dkSrmU00t/jK7rF6BZSZauA5MAaBW4i5EnJXspMwt4iqTh/L9j6fgMnbElEOfyRyfLfVbIHj/R52zHzAPe1Q==", + "dev": true, + "peerDependencies": { + "postcss": "^8.4.20" + } + }, + "node_modules/postcss-styled-syntax": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/postcss-styled-syntax/-/postcss-styled-syntax-0.6.4.tgz", + "integrity": "sha512-uWiLn+9rKgIghUYmTHvXMR6MnyPULMe9Gv3bV537Fg4FH6CA6cn21WMjKss2Qb98LUhT847tKfnRGG3FhSOgUQ==", + "dev": true, + "dependencies": { + "typescript": "^5.3.3" + }, + "engines": { + "node": ">=14.17" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", @@ -18230,6 +18522,279 @@ "webpack": "^5.0.0" } }, + "node_modules/stylelint": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.7.0.tgz", + "integrity": "sha512-Q1ATiXlz+wYr37a7TGsfvqYn2nSR3T/isw3IWlZQzFzCNoACHuGBb6xBplZXz56/uDRJHIygxjh7jbV/8isewA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + }, + { + "type": "github", + "url": "https://github.com/sponsors/stylelint" + } + ], + "dependencies": { + "@csstools/css-parser-algorithms": "^2.7.1", + "@csstools/css-tokenizer": "^2.4.1", + "@csstools/media-query-list-parser": "^2.1.13", + "@csstools/selector-specificity": "^3.1.1", + "@dual-bundle/import-meta-resolve": "^4.1.0", + "balanced-match": "^2.0.0", + "colord": "^2.9.3", + "cosmiconfig": "^9.0.0", + "css-functions-list": "^3.2.2", + "css-tree": "^2.3.1", + "debug": "^4.3.5", + "fast-glob": "^3.3.2", + "fastest-levenshtein": "^1.0.16", + "file-entry-cache": "^9.0.0", + "global-modules": "^2.0.0", + "globby": "^11.1.0", + "globjoin": "^0.1.4", + "html-tags": "^3.3.1", + "ignore": "^5.3.1", + "imurmurhash": "^0.1.4", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.34.0", + "mathml-tag-names": "^2.1.3", + "meow": "^13.2.0", + "micromatch": "^4.0.7", + "normalize-path": "^3.0.0", + "picocolors": "^1.0.1", + "postcss": "^8.4.39", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^7.0.0", + "postcss-selector-parser": "^6.1.0", + "postcss-value-parser": "^4.2.0", + "resolve-from": "^5.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^7.1.0", + "supports-hyperlinks": "^3.0.0", + "svg-tags": "^1.0.0", + "table": "^6.8.2", + "write-file-atomic": "^5.0.1" + }, + "bin": { + "stylelint": "bin/stylelint.mjs" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/stylelint-config-recommended": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-14.0.1.tgz", + "integrity": "sha512-bLvc1WOz/14aPImu/cufKAZYfXs/A/owZfSMZ4N+16WGXLoX5lOir53M6odBxvhgmgdxCVnNySJmZKx73T93cg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + }, + { + "type": "github", + "url": "https://github.com/sponsors/stylelint" + } + ], + "engines": { + "node": ">=18.12.0" + }, + "peerDependencies": { + "stylelint": "^16.1.0" + } + }, + "node_modules/stylelint-config-standard": { + "version": "36.0.1", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-36.0.1.tgz", + "integrity": "sha512-8aX8mTzJ6cuO8mmD5yon61CWuIM4UD8Q5aBcWKGSf6kg+EC3uhB+iOywpTK4ca6ZL7B49en8yanOFtUW0qNzyw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + }, + { + "type": "github", + "url": "https://github.com/sponsors/stylelint" + } + ], + "dependencies": { + "stylelint-config-recommended": "^14.0.1" + }, + "engines": { + "node": ">=18.12.0" + }, + "peerDependencies": { + "stylelint": "^16.1.0" + } + }, + "node_modules/stylelint-order": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-6.0.4.tgz", + "integrity": "sha512-0UuKo4+s1hgQ/uAxlYU4h0o0HS4NiQDud0NAUNI0aa8FJdmYHA5ZZTFHiV5FpmE3071e9pZx5j0QpVJW5zOCUA==", + "dev": true, + "dependencies": { + "postcss": "^8.4.32", + "postcss-sorting": "^8.0.2" + }, + "peerDependencies": { + "stylelint": "^14.0.0 || ^15.0.0 || ^16.0.1" + } + }, + "node_modules/stylelint/node_modules/balanced-match": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", + "dev": true + }, + "node_modules/stylelint/node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/stylelint/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/stylelint/node_modules/file-entry-cache": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.0.0.tgz", + "integrity": "sha512-6MgEugi8p2tiUhqO7GnPsmbCCzj0YRCwwaTbpGRyKZesjRSzkqkAE9fPp7V2yMs5hwfgbQLgdvSSkGNg1s5Uvw==", + "dev": true, + "dependencies": { + "flat-cache": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/stylelint/node_modules/flat-cache": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-5.0.0.tgz", + "integrity": "sha512-JrqFmyUl2PnPi1OvLyTVHnQvwQ0S+e6lGSwu8OkAZlSaNIZciTY2H/cOOROxsBA1m/LZNHDsqAgDZt6akWcjsQ==", + "dev": true, + "dependencies": { + "flatted": "^3.3.1", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/stylelint/node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/stylelint/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/string-width/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/stylelint/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/stylelint/node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/stylis": { "version": "4.2.0", "license": "MIT" @@ -18248,6 +18813,31 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/supports-hyperlinks": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", + "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/supports-hyperlinks/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/supports-preserve-symlinks-flag": { "version": "1.0.0", "license": "MIT", @@ -18258,6 +18848,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", + "dev": true + }, "node_modules/swc-loader": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/swc-loader/-/swc-loader-0.2.6.tgz", @@ -18276,6 +18872,114 @@ "dev": true, "license": "MIT" }, + "node_modules/table": { + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", + "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/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/table/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/table/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/table/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/table/node_modules/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==", + "dev": true + }, + "node_modules/table/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/table/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/tapable": { "version": "2.2.1", "dev": true, diff --git a/frontend/package.json b/frontend/package.json index b25c93bb..8ccd3272 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,6 +9,7 @@ "build-prod": "webpack --config webpack.config.prod.js", "test": "jest --watch", "lint": "npx eslint --ext .ts,.tsx .", + "lint:styled": "stylelint './src/**/*.styled.ts' --fix", "prepare": "cd .. && husky frontend/.husky", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build" @@ -68,8 +69,12 @@ "jest-environment-jsdom": "^29.7.0", "lint-staged": "^15.2.7", "msw": "^2.3.1", + "postcss-styled-syntax": "^0.6.4", "prettier": "^3.3.2", "storybook": "^8.2.2", + "stylelint": "^16.7.0", + "stylelint-config-standard": "^36.0.1", + "stylelint-order": "^6.0.4", "ts-loader": "^9.5.1", "typescript": "^5.5.3", "webpack": "^5.92.1", From cab6dea73eced5f4037c1527f570ca37896b043d Mon Sep 17 00:00:00 2001 From: novice0840 Date: Tue, 16 Jul 2024 02:56:11 +0900 Subject: [PATCH 0017/1013] =?UTF-8?q?feat:=20Timer=20component=20storybook?= =?UTF-8?q?=20=EC=97=B0=EB=8F=99=20#5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/.gitkeep | 0 frontend/src/components/Timer/Timer.stories.ts | 16 ++++++++++++++++ frontend/src/components/Timer/Timer.styled.ts | 6 ++++++ frontend/src/components/Timer/Timer.tsx | 7 +++++++ 4 files changed, 29 insertions(+) delete mode 100644 frontend/src/components/.gitkeep create mode 100644 frontend/src/components/Timer/Timer.stories.ts create mode 100644 frontend/src/components/Timer/Timer.styled.ts create mode 100644 frontend/src/components/Timer/Timer.tsx diff --git a/frontend/src/components/.gitkeep b/frontend/src/components/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/frontend/src/components/Timer/Timer.stories.ts b/frontend/src/components/Timer/Timer.stories.ts new file mode 100644 index 00000000..4683363d --- /dev/null +++ b/frontend/src/components/Timer/Timer.stories.ts @@ -0,0 +1,16 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import Timer from './Timer'; + +const meta: Meta = { + title: 'Title', + component: Timer, +}; + +type Story = StoryObj; + +export default meta; + +export const Primary: Story = { + args: {}, +}; diff --git a/frontend/src/components/Timer/Timer.styled.ts b/frontend/src/components/Timer/Timer.styled.ts new file mode 100644 index 00000000..bd6b7a17 --- /dev/null +++ b/frontend/src/components/Timer/Timer.styled.ts @@ -0,0 +1,6 @@ +import { css } from '@emotion/react'; + +export const layout = css` + width: 200px; + height: 50px; +`; diff --git a/frontend/src/components/Timer/Timer.tsx b/frontend/src/components/Timer/Timer.tsx new file mode 100644 index 00000000..7a7d1832 --- /dev/null +++ b/frontend/src/components/Timer/Timer.tsx @@ -0,0 +1,7 @@ +import { layout } from './Timer.styled'; + +const Timer = () => { + return
this is timer
; +}; + +export default Timer; From bed51e960ee3cee0edec5abdee28da1c7cdc42bc Mon Sep 17 00:00:00 2001 From: novice0840 Date: Tue, 16 Jul 2024 02:56:55 +0900 Subject: [PATCH 0018/1013] =?UTF-8?q?chore:=20lint-style=20=EB=AA=85?= =?UTF-8?q?=EB=A0=B9=EC=96=B4=20=EB=B3=80=EA=B2=BD=20#5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/package.json b/frontend/package.json index 8ccd3272..81d82dc2 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,7 +9,7 @@ "build-prod": "webpack --config webpack.config.prod.js", "test": "jest --watch", "lint": "npx eslint --ext .ts,.tsx .", - "lint:styled": "stylelint './src/**/*.styled.ts' --fix", + "lint:styled": "stylelint ./src/**/*.styled.ts --fix", "prepare": "cd .. && husky frontend/.husky", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build" From a2e52ef485fe1b39e1ecdbcaf3dd99b8bfec6438 Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 16 Jul 2024 03:19:56 +0900 Subject: [PATCH 0019/1013] =?UTF-8?q?chore:=20=EC=8A=A4=ED=83=80=EC=9D=BC?= =?UTF-8?q?=20=EB=A6=B0=ED=8A=B8=20=EC=8B=A4=ED=96=89=20=EB=AA=85=EB=A0=B9?= =?UTF-8?q?=EC=96=B4=20=EC=88=98=EC=A0=95=20#7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/package.json b/frontend/package.json index 8ccd3272..81d82dc2 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,7 +9,7 @@ "build-prod": "webpack --config webpack.config.prod.js", "test": "jest --watch", "lint": "npx eslint --ext .ts,.tsx .", - "lint:styled": "stylelint './src/**/*.styled.ts' --fix", + "lint:styled": "stylelint ./src/**/*.styled.ts --fix", "prepare": "cd .. && husky frontend/.husky", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build" From bb74be0a3ab3313abacf3ddf4a0bf288fd0ef14d Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 16 Jul 2024 03:20:51 +0900 Subject: [PATCH 0020/1013] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?#7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/.gitkeep | 0 frontend/src/styles/.gitkeep | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 frontend/src/components/.gitkeep delete mode 100644 frontend/src/styles/.gitkeep diff --git a/frontend/src/components/.gitkeep b/frontend/src/components/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/frontend/src/styles/.gitkeep b/frontend/src/styles/.gitkeep deleted file mode 100644 index e69de29b..00000000 From d4c318e04d0ecaf85318f84cda59da0e7108638d Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 16 Jul 2024 03:30:38 +0900 Subject: [PATCH 0021/1013] =?UTF-8?q?design:=20=EA=B8=80=EB=A1=9C=EB=B2=8C?= =?UTF-8?q?=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=A0=81=EC=9A=A9=20#7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/index.tsx | 10 +- frontend/src/styles/GlobalStyle.ts | 149 +++++++++++++++++++++++++++++ frontend/src/styles/Theme.ts | 10 ++ frontend/src/styles/emotion.d.ts | 7 ++ 4 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 frontend/src/styles/GlobalStyle.ts create mode 100644 frontend/src/styles/Theme.ts create mode 100644 frontend/src/styles/emotion.d.ts diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 4f23d523..c2660f11 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -1,6 +1,9 @@ +import { Global, ThemeProvider } from '@emotion/react'; import ReactDOM from 'react-dom/client'; import App from './App'; +import GlobalStyle from './styles/GlobalStyle'; +import { Theme } from './styles/Theme'; const enableMocking = async () => { if (process.env.NODE_ENV !== 'development') { @@ -13,5 +16,10 @@ const enableMocking = async () => { }; enableMocking().then(() => { - ReactDOM.createRoot(document.getElementById('root')!).render(); + ReactDOM.createRoot(document.getElementById('root')!).render( + + + + , + ); }); diff --git a/frontend/src/styles/GlobalStyle.ts b/frontend/src/styles/GlobalStyle.ts new file mode 100644 index 00000000..7761966b --- /dev/null +++ b/frontend/src/styles/GlobalStyle.ts @@ -0,0 +1,149 @@ +import { css } from '@emotion/react'; + +const reset = css` + html, + body, + div, + span, + applet, + object, + iframe, + h1, + h2, + h3, + h4, + h5, + h6, + p, + blockquote, + pre, + a, + abbr, + acronym, + address, + big, + cite, + code, + del, + dfn, + em, + img, + ins, + kbd, + q, + s, + samp, + small, + strike, + strong, + sub, + sup, + tt, + var, + b, + u, + i, + center, + dl, + dt, + dd, + ol, + ul, + li, + fieldset, + form, + label, + legend, + table, + caption, + tbody, + tfoot, + thead, + tr, + th, + td, + article, + aside, + canvas, + details, + embed, + figure, + figcaption, + footer, + header, + hgroup, + menu, + nav, + output, + ruby, + section, + summary, + time, + mark, + audio, + video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; + } + + article, + aside, + details, + figcaption, + figure, + footer, + header, + hgroup, + menu, + nav, + section { + display: block; + } + + body { + line-height: 1; + } + + ol, + ul { + list-style: none; + } + + blockquote, + q { + quotes: none; + } + + blockquote:before, + blockquote:after, + q:before, + q:after { + content: ''; + content: none; + } + + table { + border-collapse: collapse; + border-spacing: 0; + } +`; + +const GlobalStyle = css` + ${reset} + + html { + font-size: 10px; + } + + #root { + width: 32rem; + height: 56.8rem; + margin: 0 auto; + } +`; + +export default GlobalStyle; diff --git a/frontend/src/styles/Theme.ts b/frontend/src/styles/Theme.ts new file mode 100644 index 00000000..1e1de99c --- /dev/null +++ b/frontend/src/styles/Theme.ts @@ -0,0 +1,10 @@ +const color = { + // primary color + peanut300: '#FFF4DF', + peanut400: '#FFDD9A', + peanut500: '#F4BB4E', +} as const; + +export const Theme = { + color, +}; diff --git a/frontend/src/styles/emotion.d.ts b/frontend/src/styles/emotion.d.ts new file mode 100644 index 00000000..70587c20 --- /dev/null +++ b/frontend/src/styles/emotion.d.ts @@ -0,0 +1,7 @@ +import '@emotion/react'; + +declare module '@emotion/react' { + export interface Theme { + color: { [key: string]: string }; + } +} From 853fc5fac0e6093546da5fa06025cf08e7904dbc Mon Sep 17 00:00:00 2001 From: novice0840 Date: Tue, 16 Jul 2024 04:05:53 +0900 Subject: [PATCH 0022/1013] =?UTF-8?q?feat:=20Timer=20UI=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20#5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.gitignore | 3 +- frontend/package-lock.json | 41 +++++++++++++------ frontend/src/App.tsx | 3 ++ frontend/src/components/Timer/Timer.styled.ts | 8 +++- frontend/src/components/Timer/Timer.tsx | 2 +- 5 files changed, 41 insertions(+), 16 deletions(-) diff --git a/frontend/.gitignore b/frontend/.gitignore index a78f7809..f4ea8483 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -27,4 +27,5 @@ dist-ssr .env.development .env.production -*storybook.log \ No newline at end of file +*storybook.log +storybook-static \ No newline at end of file diff --git a/frontend/package-lock.json b/frontend/package-lock.json index b017fb65..862797cc 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -26,6 +26,7 @@ "@storybook/addon-interactions": "^8.2.2", "@storybook/addon-links": "^8.2.2", "@storybook/addon-onboarding": "^8.2.2", + "@storybook/addon-themes": "^8.2.3", "@storybook/addon-webpack5-compiler-swc": "^1.0.4", "@storybook/blocks": "^8.2.2", "@storybook/react": "^8.2.2", @@ -4209,6 +4210,22 @@ "storybook": "^8.2.2" } }, + "node_modules/@storybook/addon-themes": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@storybook/addon-themes/-/addon-themes-8.2.3.tgz", + "integrity": "sha512-0Be9zEvhAGCEt0+z+XL09EkclHhrKCNX1GbKO40HiFlJTzWDDBJb6wyY8V4dFq4eU/144zQOdC9DHlXS7WSMRw==", + "dev": true, + "dependencies": { + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.3" + } + }, "node_modules/@storybook/addon-toolbars": { "version": "8.2.2", "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.2.2.tgz", @@ -4609,15 +4626,15 @@ } }, "node_modules/@storybook/codemod": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-8.2.2.tgz", - "integrity": "sha512-wRUVKLHVUhbLJYKW3QOufUxJGwaUT4jTCD8+HOGpHPdJO3NrwXu186xt4tuPZO2Y/NnacPeCQPsaK5ok4O8o7A==", + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-8.2.3.tgz", + "integrity": "sha512-mAc22OJthMr1oaGVKRbO05sveTUhcWhdgN4nQKf7wLfXjW73mMgrblao+mxiWIfhXIjbOB5xgw3Csi9pcy6Kkw==", "dev": true, "dependencies": { "@babel/core": "^7.24.4", "@babel/preset-env": "^7.24.4", "@babel/types": "^7.24.0", - "@storybook/core": "8.2.2", + "@storybook/core": "8.2.3", "@storybook/csf": "0.1.11", "@types/cross-spawn": "^6.0.2", "cross-spawn": "^7.0.3", @@ -4678,9 +4695,9 @@ } }, "node_modules/@storybook/core": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.2.2.tgz", - "integrity": "sha512-L4ojYI+Os/i5bCReDIlFgEDQSS94mbJlNU9WRzEGZpqNC5/hbFEC9Tip7P1MiRx9NrewkzU7b+UCP7mi3e4drQ==", + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.2.3.tgz", + "integrity": "sha512-6CV6P8ES7E+vQZEuJTdLhgC3Lo7iRy+tpc/3przT25EStzNTR3TW2X31KUn7BfY2fuxCFPzftPaSJ/LEi7zHqg==", "dev": true, "dependencies": { "@storybook/csf": "0.1.11", @@ -18015,15 +18032,15 @@ } }, "node_modules/storybook": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.2.2.tgz", - "integrity": "sha512-xDT9gyzAEFQNeK7P+Mj/8bNzN+fbm6/4D6ihdSzmczayjydpNjMs74HDHMY6S4Bfu6tRVyEK2ALPGnr6ZVofBA==", + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.2.3.tgz", + "integrity": "sha512-uGjoFasTDWaeLp+pz8jCdKfSOvBTNEBpGf2C+pwZkJpd5CHrUlq4dkfE0/Kv/MtyQI1W9Fgbinbj7ggNe0D3Cg==", "dev": true, "dependencies": { "@babel/core": "^7.24.4", "@babel/types": "^7.24.0", - "@storybook/codemod": "8.2.2", - "@storybook/core": "8.2.2", + "@storybook/codemod": "8.2.3", + "@storybook/core": "8.2.3", "@types/semver": "^7.3.4", "@yarnpkg/fslib": "2.10.3", "@yarnpkg/libzip": "2.3.0", diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 360521c5..6a1e50f1 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,6 +1,9 @@ +import Timer from '@/components/Timer/Timer'; + const App = () => { return (
+

ddang-kong

); diff --git a/frontend/src/components/Timer/Timer.styled.ts b/frontend/src/components/Timer/Timer.styled.ts index bd6b7a17..f88b9459 100644 --- a/frontend/src/components/Timer/Timer.styled.ts +++ b/frontend/src/components/Timer/Timer.styled.ts @@ -1,6 +1,10 @@ +/** @jsxImportSource @emotion/react */ import { css } from '@emotion/react'; export const layout = css` - width: 200px; - height: 50px; + background: linear-gradient(to right, #ffcc6a, #fff0d4); + width: 275px; + height: 34px; + border: none; + border-radius: 17px; /* height의 절반 */ `; diff --git a/frontend/src/components/Timer/Timer.tsx b/frontend/src/components/Timer/Timer.tsx index 7a7d1832..61b544d0 100644 --- a/frontend/src/components/Timer/Timer.tsx +++ b/frontend/src/components/Timer/Timer.tsx @@ -1,7 +1,7 @@ import { layout } from './Timer.styled'; const Timer = () => { - return
this is timer
; + return
; }; export default Timer; From 651449c65325aa1ec59542954a57091400674503 Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 16 Jul 2024 04:49:55 +0900 Subject: [PATCH 0023/1013] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?#7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/assets/images/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 frontend/src/assets/images/.gitkeep diff --git a/frontend/src/assets/images/.gitkeep b/frontend/src/assets/images/.gitkeep deleted file mode 100644 index e69de29b..00000000 From e69d6481facb767fdbbe58c9608e9fe91ee946ef Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 16 Jul 2024 05:04:36 +0900 Subject: [PATCH 0024/1013] =?UTF-8?q?design:=20header=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84=20#7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/assets/images/homeIcon.svg | 1 + frontend/src/assets/images/settingsIcon.svg | 1 + .../components/layout/header/Header.styled.ts | 12 ++++++++++ .../src/components/layout/header/Header.tsx | 24 +++++++++++++++++++ 4 files changed, 38 insertions(+) create mode 100644 frontend/src/assets/images/homeIcon.svg create mode 100644 frontend/src/assets/images/settingsIcon.svg create mode 100644 frontend/src/components/layout/header/Header.styled.ts create mode 100644 frontend/src/components/layout/header/Header.tsx diff --git a/frontend/src/assets/images/homeIcon.svg b/frontend/src/assets/images/homeIcon.svg new file mode 100644 index 00000000..7bb31b23 --- /dev/null +++ b/frontend/src/assets/images/homeIcon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/assets/images/settingsIcon.svg b/frontend/src/assets/images/settingsIcon.svg new file mode 100644 index 00000000..19c27265 --- /dev/null +++ b/frontend/src/assets/images/settingsIcon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/components/layout/header/Header.styled.ts b/frontend/src/components/layout/header/Header.styled.ts new file mode 100644 index 00000000..25fae278 --- /dev/null +++ b/frontend/src/components/layout/header/Header.styled.ts @@ -0,0 +1,12 @@ +import { css } from '@emotion/react'; + +export const headerLayout = css` + display: flex; + justify-content: space-between; + align-items: center; +`; + +export const gameTitle = css` + font-weight: bold; + font-size: 1.6rem; +`; diff --git a/frontend/src/components/layout/header/Header.tsx b/frontend/src/components/layout/header/Header.tsx new file mode 100644 index 00000000..6c79eaaa --- /dev/null +++ b/frontend/src/components/layout/header/Header.tsx @@ -0,0 +1,24 @@ +import { gameTitle, headerLayout } from './Header.styled'; + +import HomeIcon from '@/assets/images/homeIcon.svg'; +import SettingsIcon from '@/assets/images/settingsIcon.svg'; + +interface HeaderProps { + title: string; +} + +const Header = ({ title }: HeaderProps) => { + return ( +
+ + {title} + +
+ ); +}; + +export default Header; From fec56eef4808901a265509969ae71e92640e2698 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Tue, 16 Jul 2024 05:06:18 +0900 Subject: [PATCH 0025/1013] =?UTF-8?q?feat:=20selectContainer=20UI=20markup?= =?UTF-8?q?=20=EC=99=84=EB=A3=8C=20#5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/App.tsx | 4 ++-- .../SelectContainer/SelectContainer.tsx | 19 +++++++++++++++++++ .../SelectContainer/SelectCotainer.styled.ts | 16 ++++++++++++++++ .../SelectOption/SelectOption.styled.ts | 15 +++++++++++++++ .../components/SelectOption/SelectOption.tsx | 9 +++++++++ frontend/src/components/Timer/Timer.styled.ts | 1 - .../components/common/Button/Button.styled.ts | 9 +++++++++ .../src/components/common/Button/Button.tsx | 7 +++++++ 8 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 frontend/src/components/SelectContainer/SelectContainer.tsx create mode 100644 frontend/src/components/SelectContainer/SelectCotainer.styled.ts create mode 100644 frontend/src/components/SelectOption/SelectOption.styled.ts create mode 100644 frontend/src/components/SelectOption/SelectOption.tsx create mode 100644 frontend/src/components/common/Button/Button.styled.ts create mode 100644 frontend/src/components/common/Button/Button.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 6a1e50f1..cab7b1a8 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,9 +1,9 @@ -import Timer from '@/components/Timer/Timer'; +import SelectContainer from '@/components/SelectContainer/SelectContainer'; const App = () => { return (
- +

ddang-kong

); diff --git a/frontend/src/components/SelectContainer/SelectContainer.tsx b/frontend/src/components/SelectContainer/SelectContainer.tsx new file mode 100644 index 00000000..3bff1b3e --- /dev/null +++ b/frontend/src/components/SelectContainer/SelectContainer.tsx @@ -0,0 +1,19 @@ +import { layout, selectSection } from './SelectCotainer.styled'; + +import Button from '@/components/common/Button/Button'; +import SelectOption from '@/components/SelectOption/SelectOption'; + +const SelectContainer = () => { + return ( +
+
+ + VS + +
+
+ ); +}; + +export default SelectContainer; diff --git a/frontend/src/components/SelectContainer/SelectCotainer.styled.ts b/frontend/src/components/SelectContainer/SelectCotainer.styled.ts new file mode 100644 index 00000000..029cc576 --- /dev/null +++ b/frontend/src/components/SelectContainer/SelectCotainer.styled.ts @@ -0,0 +1,16 @@ +import { css } from '@emotion/react'; + +export const layout = css` + display: flex; + flex-direction: column; + align-items: center; + gap: 50px; + border: solid 1px; +`; + +export const selectSection = css` + display: flex; + align-items: center; + gap: 12px; + justify-content: space-between; +`; diff --git a/frontend/src/components/SelectOption/SelectOption.styled.ts b/frontend/src/components/SelectOption/SelectOption.styled.ts new file mode 100644 index 00000000..2d6b0923 --- /dev/null +++ b/frontend/src/components/SelectOption/SelectOption.styled.ts @@ -0,0 +1,15 @@ +import { css } from '@emotion/react'; + +export const layout = css` + width: 114px; + height: 168px; + border-radius: 30px; /* 둥근 모서리 */ + background-color: #fff4d4; + display: flex; + justify-content: center; + align-items: center; + text-align: center; + font-size: 18px; /* 텍스트 크기 */ + font-weight: bold; /* 텍스트 굵기 */ + color: #000; /* 텍스트 색상 */ +`; diff --git a/frontend/src/components/SelectOption/SelectOption.tsx b/frontend/src/components/SelectOption/SelectOption.tsx new file mode 100644 index 00000000..4b9c1fcf --- /dev/null +++ b/frontend/src/components/SelectOption/SelectOption.tsx @@ -0,0 +1,9 @@ +import React from 'react'; + +import { layout } from './SelectOption.styled'; + +const SelectOption = () => { + return
this is select option
; +}; + +export default SelectOption; diff --git a/frontend/src/components/Timer/Timer.styled.ts b/frontend/src/components/Timer/Timer.styled.ts index f88b9459..5b65549b 100644 --- a/frontend/src/components/Timer/Timer.styled.ts +++ b/frontend/src/components/Timer/Timer.styled.ts @@ -1,4 +1,3 @@ -/** @jsxImportSource @emotion/react */ import { css } from '@emotion/react'; export const layout = css` diff --git a/frontend/src/components/common/Button/Button.styled.ts b/frontend/src/components/common/Button/Button.styled.ts new file mode 100644 index 00000000..28e01364 --- /dev/null +++ b/frontend/src/components/common/Button/Button.styled.ts @@ -0,0 +1,9 @@ +import { css } from '@emotion/react'; + +export const layout = css` + width: 120px; + height: 40px; + border: 0; + border-radius: 24px; + background-color: #ffcc6a; +`; diff --git a/frontend/src/components/common/Button/Button.tsx b/frontend/src/components/common/Button/Button.tsx new file mode 100644 index 00000000..e5b4d558 --- /dev/null +++ b/frontend/src/components/common/Button/Button.tsx @@ -0,0 +1,7 @@ +import { layout } from './Button.styled'; + +const Button = () => { + return ; +}; + +export default Button; From f5a926ba8ed1fc433c18c6f759dc92cfeda1a892 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Tue, 16 Jul 2024 03:19:56 +0900 Subject: [PATCH 0026/1013] =?UTF-8?q?feat:=20=EC=A7=88=EB=AC=B8=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EB=B6=88=EB=9F=AC=EC=98=A4?= =?UTF-8?q?=EB=8A=94=20get=20=EC=9A=94=EC=B2=AD=20mocking=20#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/package.json | 3 ++- frontend/src/apis/question.ts | 13 +++++++++++++ frontend/src/mocks/data/.gitkeep | 0 frontend/src/mocks/data/question.json | 13 +++++++++++++ frontend/src/mocks/handlers/index.ts | 4 +++- frontend/src/mocks/handlers/questionHandler.ts | 11 +++++++++++ frontend/tsconfig.json | 5 +++-- 7 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 frontend/src/apis/question.ts delete mode 100644 frontend/src/mocks/data/.gitkeep create mode 100644 frontend/src/mocks/data/question.json create mode 100644 frontend/src/mocks/handlers/questionHandler.ts diff --git a/frontend/package.json b/frontend/package.json index 8ccd3272..4af98946 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,7 +9,7 @@ "build-prod": "webpack --config webpack.config.prod.js", "test": "jest --watch", "lint": "npx eslint --ext .ts,.tsx .", - "lint:styled": "stylelint './src/**/*.styled.ts' --fix", + "lint:styled": "stylelint ./src/**/*.styled.ts --fix", "prepare": "cd .. && husky frontend/.husky", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build" @@ -73,6 +73,7 @@ "prettier": "^3.3.2", "storybook": "^8.2.2", "stylelint": "^16.7.0", + "stylelint-config-clean-order": "^6.1.0", "stylelint-config-standard": "^36.0.1", "stylelint-order": "^6.0.4", "ts-loader": "^9.5.1", diff --git a/frontend/src/apis/question.ts b/frontend/src/apis/question.ts new file mode 100644 index 00000000..8a508d0d --- /dev/null +++ b/frontend/src/apis/question.ts @@ -0,0 +1,13 @@ +const BASE_URL = process.env.NODE_ENV === 'production' ? process.env.API_BASE_URL : ''; + +const URL = { + question: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/question`, +}; + +export const fetchQuestion = async (roomId = 1) => { + const res = await fetch(URL.question(roomId)); + + const data = await res.json(); + + return data; +}; diff --git a/frontend/src/mocks/data/.gitkeep b/frontend/src/mocks/data/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/frontend/src/mocks/data/question.json b/frontend/src/mocks/data/question.json new file mode 100644 index 00000000..58b3443d --- /dev/null +++ b/frontend/src/mocks/data/question.json @@ -0,0 +1,13 @@ +{ + "questionId": 1, + "category": "연애", + "title": "초절정 스위스 여신과 가슴이 두근거리는 데이트 VS 초절정 스미스머신과 가슴 이두근 고립 웨이트", + "firstOption": { + "optionId": 1, + "content": "초절정 스위스 여신과 가슴이 두근거리는 데이트" + }, + "secondOption": { + "optionId": 2, + "content": "초절정 스미스머신과 가슴 이두근 고립 웨이트" + } +} diff --git a/frontend/src/mocks/handlers/index.ts b/frontend/src/mocks/handlers/index.ts index 0f3710c6..04ef6ccd 100644 --- a/frontend/src/mocks/handlers/index.ts +++ b/frontend/src/mocks/handlers/index.ts @@ -1 +1,3 @@ -export const handlers = []; +import { questionHandler } from './questionHandler'; + +export const handlers = [...questionHandler]; diff --git a/frontend/src/mocks/handlers/questionHandler.ts b/frontend/src/mocks/handlers/questionHandler.ts new file mode 100644 index 00000000..3b3fd3a0 --- /dev/null +++ b/frontend/src/mocks/handlers/questionHandler.ts @@ -0,0 +1,11 @@ +import { http, HttpResponse } from 'msw'; + +import QUESTION from '../data/question.json'; + +const fetchQuestionHandler = () => { + return HttpResponse.json(QUESTION); +}; + +export const questionHandler = [ + http.get('/api/balances/rooms/:roomId/question', fetchQuestionHandler), +]; diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index 499f49e7..e0b5a5d0 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -6,10 +6,11 @@ "outDir": "./dist", // 컴파일된 파일이 저장될 출력 디렉토리 지정 "noImplicitAny": true, // 암시적 any를 허용하지 않음 "strict": true, // 엄격한 타입 검사 - "jsx": "react-jsx", // React 프로젝트에서 JSX를 사용하기 위해 필요 - "jsxImportSource": "@emotion/react", // 새로운 JSX 변환 방식(React 17+)으로 css prop 사용하기 위해 필요 + "jsx": "react-jsx", // 새로운 JSX 변환 방식(React 17+)으로 css prop 사용하기 위해 필요 + "jsxImportSource": "@emotion/react", // React jsx 함수가 아닌 emotion jsx 함수 사용 "allowSyntheticDefaultImports": true, // default export 가 없어도 import 허용 "sourceMap": true, // 디버깅 시 어떤 파일에서 에러났는지 추적 용이 + "resolveJsonModule": true, // JSON 파일 resolve "baseUrl": ".", // 모듈 해석 기본 경로 "paths": { // 경로 별칭 설정 From 432c7f78cc6f539cc06d335886d74082335802f2 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Tue, 16 Jul 2024 03:28:28 +0900 Subject: [PATCH 0027/1013] =?UTF-8?q?feat:=20=ED=88=AC=ED=91=9C=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=EB=A5=BC=20=EB=B0=98=EC=98=81=20post=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=20mocking=20#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/.gitkeep | 0 frontend/src/apis/question.ts | 16 ++++++++++++++++ frontend/src/mocks/handlers/index.ts | 3 ++- frontend/src/mocks/handlers/voteHandler.ts | 16 ++++++++++++++++ 4 files changed, 34 insertions(+), 1 deletion(-) delete mode 100644 frontend/src/apis/.gitkeep create mode 100644 frontend/src/mocks/handlers/voteHandler.ts diff --git a/frontend/src/apis/.gitkeep b/frontend/src/apis/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/frontend/src/apis/question.ts b/frontend/src/apis/question.ts index 8a508d0d..68050fd3 100644 --- a/frontend/src/apis/question.ts +++ b/frontend/src/apis/question.ts @@ -2,6 +2,8 @@ const BASE_URL = process.env.NODE_ENV === 'production' ? process.env.API_BASE_UR const URL = { question: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/question`, + vote: (roomId: number, questionId: number) => + `${BASE_URL}/api/balances/rooms/${roomId}/questions/${questionId}/votes`, }; export const fetchQuestion = async (roomId = 1) => { @@ -11,3 +13,17 @@ export const fetchQuestion = async (roomId = 1) => { return data; }; + +export const voteQuestion = async (choiceId: number, roomId = 1, questionId = 1) => { + const res = await fetch(URL.vote(roomId, questionId), { + method: 'POST', + body: JSON.stringify({ + memberId: 1, + choiceId, + }), + }); + + const data = await res.json(); + + return data; +}; diff --git a/frontend/src/mocks/handlers/index.ts b/frontend/src/mocks/handlers/index.ts index 04ef6ccd..ddef2083 100644 --- a/frontend/src/mocks/handlers/index.ts +++ b/frontend/src/mocks/handlers/index.ts @@ -1,3 +1,4 @@ import { questionHandler } from './questionHandler'; +import { voteHandler } from './voteHandler'; -export const handlers = [...questionHandler]; +export const handlers = [...questionHandler, ...voteHandler]; diff --git a/frontend/src/mocks/handlers/voteHandler.ts b/frontend/src/mocks/handlers/voteHandler.ts new file mode 100644 index 00000000..e8858f8a --- /dev/null +++ b/frontend/src/mocks/handlers/voteHandler.ts @@ -0,0 +1,16 @@ +import { http, HttpResponse } from 'msw'; + +const voteQuestionHandler = async ({ request }: { request: Request }) => { + const body = await request.json(); + + return HttpResponse.json( + { + choiceId: 1, + }, + { status: 201 }, + ); +}; + +export const voteHandler = [ + http.post('/api/balances/rooms/:roomId/questions/:questionId/votes', voteQuestionHandler), +]; From 20a0cd2a7c7a25af2bc2de8e1342255781aaba30 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Tue, 16 Jul 2024 04:18:40 +0900 Subject: [PATCH 0028/1013] =?UTF-8?q?feat:=20fetcher=20=EB=A5=BC=20?= =?UTF-8?q?=ED=99=9C=EC=9A=A9=ED=95=98=EC=97=AC=20API=20=EA=B3=84=EC=B8=B5?= =?UTF-8?q?=20=EC=B6=94=EC=83=81=ED=99=94=20#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/fetcher.ts | 42 +++++++++++++++++++++++++++++++++++ frontend/src/apis/question.ts | 12 +++++----- 2 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 frontend/src/apis/fetcher.ts diff --git a/frontend/src/apis/fetcher.ts b/frontend/src/apis/fetcher.ts new file mode 100644 index 00000000..66bff23a --- /dev/null +++ b/frontend/src/apis/fetcher.ts @@ -0,0 +1,42 @@ +interface RequestProps { + url: string; + method: 'GET' | 'POST' | 'DELETE' | 'PATCH' | 'PUT'; + body?: Record; + headers?: Record; +} + +type FetchProps = Omit; + +const fetcher = { + async request({ url, method, body, headers }: RequestProps) { + const response = await fetch(url, { + method, + body: body && JSON.stringify(body), + headers: headers && headers, + }); + + if (!response.ok) { + throw new Error('fetch fail error'); + } + + return response; + }, + + get({ url, headers }: FetchProps) { + return this.request({ url, method: 'GET', headers }); + }, + post({ url, body, headers }: FetchProps) { + return this.request({ url, method: 'POST', body, headers }); + }, + delete({ url, headers }: FetchProps) { + return this.request({ url, method: 'DELETE', headers }); + }, + patch({ url, body, headers }: FetchProps) { + return this.request({ url, method: 'PATCH', body, headers }); + }, + put({ url, headers }: FetchProps) { + return this.request({ url, method: 'PUT', headers }); + }, +}; + +export default fetcher; diff --git a/frontend/src/apis/question.ts b/frontend/src/apis/question.ts index 68050fd3..edd3521b 100644 --- a/frontend/src/apis/question.ts +++ b/frontend/src/apis/question.ts @@ -1,3 +1,5 @@ +import fetcher from './fetcher'; + const BASE_URL = process.env.NODE_ENV === 'production' ? process.env.API_BASE_URL : ''; const URL = { @@ -7,7 +9,7 @@ const URL = { }; export const fetchQuestion = async (roomId = 1) => { - const res = await fetch(URL.question(roomId)); + const res = await fetcher.get({ url: URL.question(roomId) }); const data = await res.json(); @@ -15,12 +17,12 @@ export const fetchQuestion = async (roomId = 1) => { }; export const voteQuestion = async (choiceId: number, roomId = 1, questionId = 1) => { - const res = await fetch(URL.vote(roomId, questionId), { - method: 'POST', - body: JSON.stringify({ + const res = await fetcher.post({ + url: URL.vote(roomId, questionId), + body: { memberId: 1, choiceId, - }), + }, }); const data = await res.json(); From 1f76d62bc8106539959fb2ae6b44f4bb970cf717 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Tue, 16 Jul 2024 04:52:09 +0900 Subject: [PATCH 0029/1013] =?UTF-8?q?refactor:=20url=20=EC=83=81=EC=88=98?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC=20=EB=B0=8F=20msw=20handler=20url=20?= =?UTF-8?q?=EC=83=81=EC=88=98=ED=99=94=20#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/question.ts | 12 +++--------- frontend/src/constants/.gitkeep | 0 frontend/src/constants/url.ts | 12 ++++++++++++ frontend/src/mocks/handlers/questionHandler.ts | 6 +++--- frontend/src/mocks/handlers/voteHandler.ts | 6 +++--- 5 files changed, 21 insertions(+), 15 deletions(-) delete mode 100644 frontend/src/constants/.gitkeep create mode 100644 frontend/src/constants/url.ts diff --git a/frontend/src/apis/question.ts b/frontend/src/apis/question.ts index edd3521b..8f99b6cb 100644 --- a/frontend/src/apis/question.ts +++ b/frontend/src/apis/question.ts @@ -1,15 +1,9 @@ import fetcher from './fetcher'; -const BASE_URL = process.env.NODE_ENV === 'production' ? process.env.API_BASE_URL : ''; - -const URL = { - question: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/question`, - vote: (roomId: number, questionId: number) => - `${BASE_URL}/api/balances/rooms/${roomId}/questions/${questionId}/votes`, -}; +import { API_URL } from '@/constants/url'; export const fetchQuestion = async (roomId = 1) => { - const res = await fetcher.get({ url: URL.question(roomId) }); + const res = await fetcher.get({ url: API_URL.question(roomId) }); const data = await res.json(); @@ -18,7 +12,7 @@ export const fetchQuestion = async (roomId = 1) => { export const voteQuestion = async (choiceId: number, roomId = 1, questionId = 1) => { const res = await fetcher.post({ - url: URL.vote(roomId, questionId), + url: API_URL.vote(roomId, questionId), body: { memberId: 1, choiceId, diff --git a/frontend/src/constants/.gitkeep b/frontend/src/constants/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/frontend/src/constants/url.ts b/frontend/src/constants/url.ts new file mode 100644 index 00000000..53584e07 --- /dev/null +++ b/frontend/src/constants/url.ts @@ -0,0 +1,12 @@ +const BASE_URL = process.env.NODE_ENV === 'production' ? process.env.API_BASE_URL : ''; + +export const API_URL = { + question: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/question`, + vote: (roomId: number, questionId: number) => + `${BASE_URL}/api/balances/rooms/${roomId}/questions/${questionId}/votes`, +}; + +export const MOCK_API_URL = { + question: '/api/balances/rooms/:roomId/question', + vote: '/api/balances/rooms/:roomId/questions/:questionId/votes', +}; diff --git a/frontend/src/mocks/handlers/questionHandler.ts b/frontend/src/mocks/handlers/questionHandler.ts index 3b3fd3a0..1fd5347e 100644 --- a/frontend/src/mocks/handlers/questionHandler.ts +++ b/frontend/src/mocks/handlers/questionHandler.ts @@ -2,10 +2,10 @@ import { http, HttpResponse } from 'msw'; import QUESTION from '../data/question.json'; +import { MOCK_API_URL } from '@/constants/url'; + const fetchQuestionHandler = () => { return HttpResponse.json(QUESTION); }; -export const questionHandler = [ - http.get('/api/balances/rooms/:roomId/question', fetchQuestionHandler), -]; +export const questionHandler = [http.get(MOCK_API_URL.question, fetchQuestionHandler)]; diff --git a/frontend/src/mocks/handlers/voteHandler.ts b/frontend/src/mocks/handlers/voteHandler.ts index e8858f8a..4ea8caff 100644 --- a/frontend/src/mocks/handlers/voteHandler.ts +++ b/frontend/src/mocks/handlers/voteHandler.ts @@ -1,5 +1,7 @@ import { http, HttpResponse } from 'msw'; +import { MOCK_API_URL } from '@/constants/url'; + const voteQuestionHandler = async ({ request }: { request: Request }) => { const body = await request.json(); @@ -11,6 +13,4 @@ const voteQuestionHandler = async ({ request }: { request: Request }) => { ); }; -export const voteHandler = [ - http.post('/api/balances/rooms/:roomId/questions/:questionId/votes', voteQuestionHandler), -]; +export const voteHandler = [http.post(MOCK_API_URL.vote, voteQuestionHandler)]; From ec14c2421617c43cc8e8bfddc4e9821e34fe721f Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Tue, 16 Jul 2024 05:12:43 +0900 Subject: [PATCH 0030/1013] =?UTF-8?q?build:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20stylelint=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/package.json b/frontend/package.json index 4af98946..81d82dc2 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -73,7 +73,6 @@ "prettier": "^3.3.2", "storybook": "^8.2.2", "stylelint": "^16.7.0", - "stylelint-config-clean-order": "^6.1.0", "stylelint-config-standard": "^36.0.1", "stylelint-order": "^6.0.4", "ts-loader": "^9.5.1", From 3fb947706ffa2d9679ce0da0982ffaac22918f34 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Tue, 16 Jul 2024 05:48:21 +0900 Subject: [PATCH 0031/1013] =?UTF-8?q?feat:=20nickname=20container=20markup?= =?UTF-8?q?=20=EC=99=84=EB=A3=8C=20#5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/App.tsx | 3 --- .../NicknameList/NicknameList.styled.ts | 20 ++++++++++++++++ .../components/NicknameList/NicknameList.tsx | 24 +++++++++++++++++++ .../SelectContainer/SelectCotainer.styled.ts | 2 +- .../SelectOption/SelectOption.styled.ts | 16 +++++++------ .../components/common/Button/Button.styled.ts | 1 + 6 files changed, 55 insertions(+), 11 deletions(-) create mode 100644 frontend/src/components/NicknameList/NicknameList.styled.ts create mode 100644 frontend/src/components/NicknameList/NicknameList.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index cab7b1a8..360521c5 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,9 +1,6 @@ -import SelectContainer from '@/components/SelectContainer/SelectContainer'; - const App = () => { return (
-

ddang-kong

); diff --git a/frontend/src/components/NicknameList/NicknameList.styled.ts b/frontend/src/components/NicknameList/NicknameList.styled.ts new file mode 100644 index 00000000..0f93cc5e --- /dev/null +++ b/frontend/src/components/NicknameList/NicknameList.styled.ts @@ -0,0 +1,20 @@ +import { css } from '@emotion/react'; + +export const layout = css` + width: 245px; + height: 154px; + display: flex; + justify-content: space-between; +`; + +export const nicknameContainer = css` + display: grid; + grid-template-columns: 1fr 1fr; + gap: 12px; +`; + +export const verticalLine = css` + width: 1px; + height: 100%; + background-color: #d9d9d9; +`; diff --git a/frontend/src/components/NicknameList/NicknameList.tsx b/frontend/src/components/NicknameList/NicknameList.tsx new file mode 100644 index 00000000..a72d8c95 --- /dev/null +++ b/frontend/src/components/NicknameList/NicknameList.tsx @@ -0,0 +1,24 @@ +import { layout, nicknameContainer, verticalLine } from './NicknameList.styled'; + +const NicknameList = () => { + const optionANicknames = ['철수', '철수', '철수', '철수', '철수', '철수', '철수', '철수', '철수']; + const optionBNicknames = ['영미', '영미', '영미']; + + return ( +
+
+ {optionANicknames.map((optionANickname) => ( + {optionANickname} + ))} +
+ +
+ {optionBNicknames.map((optionANickname) => ( + {optionANickname} + ))} +
+
+ ); +}; + +export default NicknameList; diff --git a/frontend/src/components/SelectContainer/SelectCotainer.styled.ts b/frontend/src/components/SelectContainer/SelectCotainer.styled.ts index 029cc576..8b20550e 100644 --- a/frontend/src/components/SelectContainer/SelectCotainer.styled.ts +++ b/frontend/src/components/SelectContainer/SelectCotainer.styled.ts @@ -10,7 +10,7 @@ export const layout = css` export const selectSection = css` display: flex; + justify-content: space-between; align-items: center; gap: 12px; - justify-content: space-between; `; diff --git a/frontend/src/components/SelectOption/SelectOption.styled.ts b/frontend/src/components/SelectOption/SelectOption.styled.ts index 2d6b0923..efc353ee 100644 --- a/frontend/src/components/SelectOption/SelectOption.styled.ts +++ b/frontend/src/components/SelectOption/SelectOption.styled.ts @@ -1,15 +1,17 @@ import { css } from '@emotion/react'; export const layout = css` - width: 114px; - height: 168px; - border-radius: 30px; /* 둥근 모서리 */ - background-color: #fff4d4; display: flex; justify-content: center; align-items: center; - text-align: center; - font-size: 18px; /* 텍스트 크기 */ - font-weight: bold; /* 텍스트 굵기 */ + width: 114px; + height: 168px; + + background-color: #fff4d4; + color: #000; /* 텍스트 색상 */ + font-weight: bold; /* 텍스트 굵기 */ + font-size: 18px; /* 텍스트 크기 */ + text-align: center; + border-radius: 30px; /* 둥근 모서리 */ `; diff --git a/frontend/src/components/common/Button/Button.styled.ts b/frontend/src/components/common/Button/Button.styled.ts index 28e01364..2049b7e2 100644 --- a/frontend/src/components/common/Button/Button.styled.ts +++ b/frontend/src/components/common/Button/Button.styled.ts @@ -5,5 +5,6 @@ export const layout = css` height: 40px; border: 0; border-radius: 24px; + background-color: #ffcc6a; `; From d118a659d8266055cac0e5f08b9fb6aee411aa86 Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 16 Jul 2024 06:00:31 +0900 Subject: [PATCH 0032/1013] =?UTF-8?q?design:=20button=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84=20#7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/commmon/button/Button.styled.ts | 13 +++++++++++++ .../src/components/commmon/button/Button.tsx | 17 +++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 frontend/src/components/commmon/button/Button.styled.ts create mode 100644 frontend/src/components/commmon/button/Button.tsx diff --git a/frontend/src/components/commmon/button/Button.styled.ts b/frontend/src/components/commmon/button/Button.styled.ts new file mode 100644 index 00000000..3c36a91d --- /dev/null +++ b/frontend/src/components/commmon/button/Button.styled.ts @@ -0,0 +1,13 @@ +import { css } from '@emotion/react'; + +import { Theme } from '@/styles/Theme'; + +export const buttonLayout = (active: boolean) => css` + padding: 1rem 4rem; + + background-color: ${active ? Theme.color.peanut500 : Theme.color.peanut300}; + + font-weight: bold; + font-size: 2rem; + border-radius: 2.4rem; +`; diff --git a/frontend/src/components/commmon/button/Button.tsx b/frontend/src/components/commmon/button/Button.tsx new file mode 100644 index 00000000..804ec087 --- /dev/null +++ b/frontend/src/components/commmon/button/Button.tsx @@ -0,0 +1,17 @@ +import { buttonLayout } from './Button.styled'; + +interface ButtonProps { + text: '선택' | '확인' | '다음'; + active: boolean; + onClick: () => void; +} + +const Button = ({ text, active, onClick }: ButtonProps) => { + return ( + + ); +}; + +export default Button; From 5514adc3c7e1887f21a0c12f6d1a9c3dcd48a5bc Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 16 Jul 2024 06:01:42 +0900 Subject: [PATCH 0033/1013] =?UTF-8?q?design:=20=EA=B8=80=EB=A1=9C=EB=B2=8C?= =?UTF-8?q?=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=B6=94=EA=B0=80=20#7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/styles/GlobalStyle.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/frontend/src/styles/GlobalStyle.ts b/frontend/src/styles/GlobalStyle.ts index 7761966b..22f4de84 100644 --- a/frontend/src/styles/GlobalStyle.ts +++ b/frontend/src/styles/GlobalStyle.ts @@ -130,12 +130,20 @@ const reset = css` border-collapse: collapse; border-spacing: 0; } + + button { + border: none; + outline: none; + background-color: inherit; + cursor: pointer; + } `; const GlobalStyle = css` ${reset} html { + margin-top: 3rem; font-size: 10px; } From 988cbef4b558ea900da00ffe001ab5fac96d64c8 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Tue, 16 Jul 2024 06:09:19 +0900 Subject: [PATCH 0034/1013] =?UTF-8?q?feat:=20GameResult=20markup=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C=20#5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/GameResult/GameResult.styled.ts | 9 +++++++++ frontend/src/components/GameResult/GameResult.tsx | 14 ++++++++++++++ .../components/NicknameList/NicknameList.styled.ts | 5 +++-- 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 frontend/src/components/GameResult/GameResult.styled.ts create mode 100644 frontend/src/components/GameResult/GameResult.tsx diff --git a/frontend/src/components/GameResult/GameResult.styled.ts b/frontend/src/components/GameResult/GameResult.styled.ts new file mode 100644 index 00000000..2966a5c4 --- /dev/null +++ b/frontend/src/components/GameResult/GameResult.styled.ts @@ -0,0 +1,9 @@ +import { css } from '@emotion/react'; + +export const layout = css` + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + gap: 60px; +`; diff --git a/frontend/src/components/GameResult/GameResult.tsx b/frontend/src/components/GameResult/GameResult.tsx new file mode 100644 index 00000000..d7f3e803 --- /dev/null +++ b/frontend/src/components/GameResult/GameResult.tsx @@ -0,0 +1,14 @@ +import { layout } from './GameResult.styled'; + +import Button from '@/components/common/Button/Button'; + +const GameResult = () => { + return ( +
+

게임 결과

+
+ ); +}; + +export default GameResult; diff --git a/frontend/src/components/NicknameList/NicknameList.styled.ts b/frontend/src/components/NicknameList/NicknameList.styled.ts index 0f93cc5e..25c992a1 100644 --- a/frontend/src/components/NicknameList/NicknameList.styled.ts +++ b/frontend/src/components/NicknameList/NicknameList.styled.ts @@ -1,10 +1,10 @@ import { css } from '@emotion/react'; export const layout = css` - width: 245px; - height: 154px; display: flex; justify-content: space-between; + width: 245px; + height: 154px; `; export const nicknameContainer = css` @@ -16,5 +16,6 @@ export const nicknameContainer = css` export const verticalLine = css` width: 1px; height: 100%; + background-color: #d9d9d9; `; From 14cbaa90e66ceb7a1390ce1cbbb116c2700971e6 Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 16 Jul 2024 06:22:12 +0900 Subject: [PATCH 0035/1013] =?UTF-8?q?design:=20TopicContainer=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84=20#7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../topicContainer/TopicContainer.styled.ts | 18 ++++++++++++++++++ .../topicContainer/TopicContainer.tsx | 17 +++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 frontend/src/components/topicContainer/TopicContainer.styled.ts create mode 100644 frontend/src/components/topicContainer/TopicContainer.tsx diff --git a/frontend/src/components/topicContainer/TopicContainer.styled.ts b/frontend/src/components/topicContainer/TopicContainer.styled.ts new file mode 100644 index 00000000..c88fe907 --- /dev/null +++ b/frontend/src/components/topicContainer/TopicContainer.styled.ts @@ -0,0 +1,18 @@ +import { css } from '@emotion/react'; + +export const topicLayout = css` + display: flex; + flex-direction: column; + align-items: center; + gap: 1.4rem; +`; + +export const categoryText = css` + font-weight: bold; + font-size: 1.4rem; +`; + +export const topicText = css` + font-weight: bold; + font-size: 2rem; +`; diff --git a/frontend/src/components/topicContainer/TopicContainer.tsx b/frontend/src/components/topicContainer/TopicContainer.tsx new file mode 100644 index 00000000..28490b01 --- /dev/null +++ b/frontend/src/components/topicContainer/TopicContainer.tsx @@ -0,0 +1,17 @@ +import { categoryText, topicLayout, topicText } from './TopicContainer.styled'; + +interface TopicContainerProp { + category: string; + title: string; +} + +const TopicContainer = ({ category, title }: TopicContainerProp) => { + return ( +
+ {category} + {title} +
+ ); +}; + +export default TopicContainer; From d80a3dfbb3f6e0e5b8dd512699eaa118ea9dedce Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 16 Jul 2024 07:27:16 +0900 Subject: [PATCH 0036/1013] =?UTF-8?q?refactor:=20=ED=8F=B4=EB=8D=94=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?#7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/{commmon => common}/button/Button.styled.ts | 0 frontend/src/components/{commmon => common}/button/Button.tsx | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename frontend/src/components/{commmon => common}/button/Button.styled.ts (100%) rename frontend/src/components/{commmon => common}/button/Button.tsx (100%) diff --git a/frontend/src/components/commmon/button/Button.styled.ts b/frontend/src/components/common/button/Button.styled.ts similarity index 100% rename from frontend/src/components/commmon/button/Button.styled.ts rename to frontend/src/components/common/button/Button.styled.ts diff --git a/frontend/src/components/commmon/button/Button.tsx b/frontend/src/components/common/button/Button.tsx similarity index 100% rename from frontend/src/components/commmon/button/Button.tsx rename to frontend/src/components/common/button/Button.tsx From 853c36286f3ab2e6746997aed07763105ccfc489 Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 16 Jul 2024 07:58:08 +0900 Subject: [PATCH 0037/1013] =?UTF-8?q?refactor:=20=EC=86=8C=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=EB=AA=85=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?#7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/common/button/Button.styled.ts | 13 ---------- .../src/components/common/button/Button.tsx | 17 ------------- .../components/layout/header/Header.styled.ts | 12 ---------- .../src/components/layout/header/Header.tsx | 24 ------------------- .../topicContainer/TopicContainer.styled.ts | 18 -------------- .../topicContainer/TopicContainer.tsx | 17 ------------- 6 files changed, 101 deletions(-) delete mode 100644 frontend/src/components/common/button/Button.styled.ts delete mode 100644 frontend/src/components/common/button/Button.tsx delete mode 100644 frontend/src/components/layout/header/Header.styled.ts delete mode 100644 frontend/src/components/layout/header/Header.tsx delete mode 100644 frontend/src/components/topicContainer/TopicContainer.styled.ts delete mode 100644 frontend/src/components/topicContainer/TopicContainer.tsx diff --git a/frontend/src/components/common/button/Button.styled.ts b/frontend/src/components/common/button/Button.styled.ts deleted file mode 100644 index 3c36a91d..00000000 --- a/frontend/src/components/common/button/Button.styled.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { css } from '@emotion/react'; - -import { Theme } from '@/styles/Theme'; - -export const buttonLayout = (active: boolean) => css` - padding: 1rem 4rem; - - background-color: ${active ? Theme.color.peanut500 : Theme.color.peanut300}; - - font-weight: bold; - font-size: 2rem; - border-radius: 2.4rem; -`; diff --git a/frontend/src/components/common/button/Button.tsx b/frontend/src/components/common/button/Button.tsx deleted file mode 100644 index 804ec087..00000000 --- a/frontend/src/components/common/button/Button.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { buttonLayout } from './Button.styled'; - -interface ButtonProps { - text: '선택' | '확인' | '다음'; - active: boolean; - onClick: () => void; -} - -const Button = ({ text, active, onClick }: ButtonProps) => { - return ( - - ); -}; - -export default Button; diff --git a/frontend/src/components/layout/header/Header.styled.ts b/frontend/src/components/layout/header/Header.styled.ts deleted file mode 100644 index 25fae278..00000000 --- a/frontend/src/components/layout/header/Header.styled.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { css } from '@emotion/react'; - -export const headerLayout = css` - display: flex; - justify-content: space-between; - align-items: center; -`; - -export const gameTitle = css` - font-weight: bold; - font-size: 1.6rem; -`; diff --git a/frontend/src/components/layout/header/Header.tsx b/frontend/src/components/layout/header/Header.tsx deleted file mode 100644 index 6c79eaaa..00000000 --- a/frontend/src/components/layout/header/Header.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { gameTitle, headerLayout } from './Header.styled'; - -import HomeIcon from '@/assets/images/homeIcon.svg'; -import SettingsIcon from '@/assets/images/settingsIcon.svg'; - -interface HeaderProps { - title: string; -} - -const Header = ({ title }: HeaderProps) => { - return ( -
- - {title} - -
- ); -}; - -export default Header; diff --git a/frontend/src/components/topicContainer/TopicContainer.styled.ts b/frontend/src/components/topicContainer/TopicContainer.styled.ts deleted file mode 100644 index c88fe907..00000000 --- a/frontend/src/components/topicContainer/TopicContainer.styled.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { css } from '@emotion/react'; - -export const topicLayout = css` - display: flex; - flex-direction: column; - align-items: center; - gap: 1.4rem; -`; - -export const categoryText = css` - font-weight: bold; - font-size: 1.4rem; -`; - -export const topicText = css` - font-weight: bold; - font-size: 2rem; -`; diff --git a/frontend/src/components/topicContainer/TopicContainer.tsx b/frontend/src/components/topicContainer/TopicContainer.tsx deleted file mode 100644 index 28490b01..00000000 --- a/frontend/src/components/topicContainer/TopicContainer.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { categoryText, topicLayout, topicText } from './TopicContainer.styled'; - -interface TopicContainerProp { - category: string; - title: string; -} - -const TopicContainer = ({ category, title }: TopicContainerProp) => { - return ( -
- {category} - {title} -
- ); -}; - -export default TopicContainer; From 9a9b551026b1143a184b4fa64dfde56dd7d66ba6 Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 16 Jul 2024 08:05:56 +0900 Subject: [PATCH 0038/1013] =?UTF-8?q?refactor:=20=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=EB=AA=85=20=EB=8C=80=EB=AC=B8=EC=9E=90=EB=A1=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20#7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TopicContainer/TopicContainer.styled.ts | 18 ++++++++++++++ .../TopicContainer/TopicContainer.tsx | 17 +++++++++++++ .../components/common/Button/Button.styled.ts | 13 ++++++++++ .../src/components/common/Button/Button.tsx | 17 +++++++++++++ .../components/layout/Header/Header.styled.ts | 12 ++++++++++ .../src/components/layout/Header/Header.tsx | 24 +++++++++++++++++++ 6 files changed, 101 insertions(+) create mode 100644 frontend/src/components/TopicContainer/TopicContainer.styled.ts create mode 100644 frontend/src/components/TopicContainer/TopicContainer.tsx create mode 100644 frontend/src/components/common/Button/Button.styled.ts create mode 100644 frontend/src/components/common/Button/Button.tsx create mode 100644 frontend/src/components/layout/Header/Header.styled.ts create mode 100644 frontend/src/components/layout/Header/Header.tsx diff --git a/frontend/src/components/TopicContainer/TopicContainer.styled.ts b/frontend/src/components/TopicContainer/TopicContainer.styled.ts new file mode 100644 index 00000000..c88fe907 --- /dev/null +++ b/frontend/src/components/TopicContainer/TopicContainer.styled.ts @@ -0,0 +1,18 @@ +import { css } from '@emotion/react'; + +export const topicLayout = css` + display: flex; + flex-direction: column; + align-items: center; + gap: 1.4rem; +`; + +export const categoryText = css` + font-weight: bold; + font-size: 1.4rem; +`; + +export const topicText = css` + font-weight: bold; + font-size: 2rem; +`; diff --git a/frontend/src/components/TopicContainer/TopicContainer.tsx b/frontend/src/components/TopicContainer/TopicContainer.tsx new file mode 100644 index 00000000..28490b01 --- /dev/null +++ b/frontend/src/components/TopicContainer/TopicContainer.tsx @@ -0,0 +1,17 @@ +import { categoryText, topicLayout, topicText } from './TopicContainer.styled'; + +interface TopicContainerProp { + category: string; + title: string; +} + +const TopicContainer = ({ category, title }: TopicContainerProp) => { + return ( +
+ {category} + {title} +
+ ); +}; + +export default TopicContainer; diff --git a/frontend/src/components/common/Button/Button.styled.ts b/frontend/src/components/common/Button/Button.styled.ts new file mode 100644 index 00000000..3c36a91d --- /dev/null +++ b/frontend/src/components/common/Button/Button.styled.ts @@ -0,0 +1,13 @@ +import { css } from '@emotion/react'; + +import { Theme } from '@/styles/Theme'; + +export const buttonLayout = (active: boolean) => css` + padding: 1rem 4rem; + + background-color: ${active ? Theme.color.peanut500 : Theme.color.peanut300}; + + font-weight: bold; + font-size: 2rem; + border-radius: 2.4rem; +`; diff --git a/frontend/src/components/common/Button/Button.tsx b/frontend/src/components/common/Button/Button.tsx new file mode 100644 index 00000000..804ec087 --- /dev/null +++ b/frontend/src/components/common/Button/Button.tsx @@ -0,0 +1,17 @@ +import { buttonLayout } from './Button.styled'; + +interface ButtonProps { + text: '선택' | '확인' | '다음'; + active: boolean; + onClick: () => void; +} + +const Button = ({ text, active, onClick }: ButtonProps) => { + return ( + + ); +}; + +export default Button; diff --git a/frontend/src/components/layout/Header/Header.styled.ts b/frontend/src/components/layout/Header/Header.styled.ts new file mode 100644 index 00000000..25fae278 --- /dev/null +++ b/frontend/src/components/layout/Header/Header.styled.ts @@ -0,0 +1,12 @@ +import { css } from '@emotion/react'; + +export const headerLayout = css` + display: flex; + justify-content: space-between; + align-items: center; +`; + +export const gameTitle = css` + font-weight: bold; + font-size: 1.6rem; +`; diff --git a/frontend/src/components/layout/Header/Header.tsx b/frontend/src/components/layout/Header/Header.tsx new file mode 100644 index 00000000..6c79eaaa --- /dev/null +++ b/frontend/src/components/layout/Header/Header.tsx @@ -0,0 +1,24 @@ +import { gameTitle, headerLayout } from './Header.styled'; + +import HomeIcon from '@/assets/images/homeIcon.svg'; +import SettingsIcon from '@/assets/images/settingsIcon.svg'; + +interface HeaderProps { + title: string; +} + +const Header = ({ title }: HeaderProps) => { + return ( +
+ + {title} + +
+ ); +}; + +export default Header; From 37b981785acd701a5e11bebb16edd92122e81fb9 Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 16 Jul 2024 03:20:51 +0900 Subject: [PATCH 0039/1013] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?#7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/styles/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 frontend/src/styles/.gitkeep diff --git a/frontend/src/styles/.gitkeep b/frontend/src/styles/.gitkeep deleted file mode 100644 index e69de29b..00000000 From a7b7c99989f3d00281245722e32f3e9eaf733bc6 Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 16 Jul 2024 03:30:38 +0900 Subject: [PATCH 0040/1013] =?UTF-8?q?design:=20=EA=B8=80=EB=A1=9C=EB=B2=8C?= =?UTF-8?q?=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=A0=81=EC=9A=A9=20#7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/index.tsx | 10 +- frontend/src/styles/GlobalStyle.ts | 149 +++++++++++++++++++++++++++++ frontend/src/styles/Theme.ts | 10 ++ frontend/src/styles/emotion.d.ts | 7 ++ 4 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 frontend/src/styles/GlobalStyle.ts create mode 100644 frontend/src/styles/Theme.ts create mode 100644 frontend/src/styles/emotion.d.ts diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 4f23d523..c2660f11 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -1,6 +1,9 @@ +import { Global, ThemeProvider } from '@emotion/react'; import ReactDOM from 'react-dom/client'; import App from './App'; +import GlobalStyle from './styles/GlobalStyle'; +import { Theme } from './styles/Theme'; const enableMocking = async () => { if (process.env.NODE_ENV !== 'development') { @@ -13,5 +16,10 @@ const enableMocking = async () => { }; enableMocking().then(() => { - ReactDOM.createRoot(document.getElementById('root')!).render(); + ReactDOM.createRoot(document.getElementById('root')!).render( + + + + , + ); }); diff --git a/frontend/src/styles/GlobalStyle.ts b/frontend/src/styles/GlobalStyle.ts new file mode 100644 index 00000000..7761966b --- /dev/null +++ b/frontend/src/styles/GlobalStyle.ts @@ -0,0 +1,149 @@ +import { css } from '@emotion/react'; + +const reset = css` + html, + body, + div, + span, + applet, + object, + iframe, + h1, + h2, + h3, + h4, + h5, + h6, + p, + blockquote, + pre, + a, + abbr, + acronym, + address, + big, + cite, + code, + del, + dfn, + em, + img, + ins, + kbd, + q, + s, + samp, + small, + strike, + strong, + sub, + sup, + tt, + var, + b, + u, + i, + center, + dl, + dt, + dd, + ol, + ul, + li, + fieldset, + form, + label, + legend, + table, + caption, + tbody, + tfoot, + thead, + tr, + th, + td, + article, + aside, + canvas, + details, + embed, + figure, + figcaption, + footer, + header, + hgroup, + menu, + nav, + output, + ruby, + section, + summary, + time, + mark, + audio, + video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; + } + + article, + aside, + details, + figcaption, + figure, + footer, + header, + hgroup, + menu, + nav, + section { + display: block; + } + + body { + line-height: 1; + } + + ol, + ul { + list-style: none; + } + + blockquote, + q { + quotes: none; + } + + blockquote:before, + blockquote:after, + q:before, + q:after { + content: ''; + content: none; + } + + table { + border-collapse: collapse; + border-spacing: 0; + } +`; + +const GlobalStyle = css` + ${reset} + + html { + font-size: 10px; + } + + #root { + width: 32rem; + height: 56.8rem; + margin: 0 auto; + } +`; + +export default GlobalStyle; diff --git a/frontend/src/styles/Theme.ts b/frontend/src/styles/Theme.ts new file mode 100644 index 00000000..1e1de99c --- /dev/null +++ b/frontend/src/styles/Theme.ts @@ -0,0 +1,10 @@ +const color = { + // primary color + peanut300: '#FFF4DF', + peanut400: '#FFDD9A', + peanut500: '#F4BB4E', +} as const; + +export const Theme = { + color, +}; diff --git a/frontend/src/styles/emotion.d.ts b/frontend/src/styles/emotion.d.ts new file mode 100644 index 00000000..70587c20 --- /dev/null +++ b/frontend/src/styles/emotion.d.ts @@ -0,0 +1,7 @@ +import '@emotion/react'; + +declare module '@emotion/react' { + export interface Theme { + color: { [key: string]: string }; + } +} From c308323296421d0c347642d5742f36e962851c60 Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 16 Jul 2024 04:49:55 +0900 Subject: [PATCH 0041/1013] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?#7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/assets/images/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 frontend/src/assets/images/.gitkeep diff --git a/frontend/src/assets/images/.gitkeep b/frontend/src/assets/images/.gitkeep deleted file mode 100644 index e69de29b..00000000 From d2dd4688dca0bcb9103a3b55e596185ae4765766 Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 16 Jul 2024 05:04:36 +0900 Subject: [PATCH 0042/1013] =?UTF-8?q?design:=20header=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84=20#7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/assets/images/homeIcon.svg | 1 + frontend/src/assets/images/settingsIcon.svg | 1 + .../components/layout/header/Header.styled.ts | 12 ++++++++++ .../src/components/layout/header/Header.tsx | 24 +++++++++++++++++++ 4 files changed, 38 insertions(+) create mode 100644 frontend/src/assets/images/homeIcon.svg create mode 100644 frontend/src/assets/images/settingsIcon.svg create mode 100644 frontend/src/components/layout/header/Header.styled.ts create mode 100644 frontend/src/components/layout/header/Header.tsx diff --git a/frontend/src/assets/images/homeIcon.svg b/frontend/src/assets/images/homeIcon.svg new file mode 100644 index 00000000..7bb31b23 --- /dev/null +++ b/frontend/src/assets/images/homeIcon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/assets/images/settingsIcon.svg b/frontend/src/assets/images/settingsIcon.svg new file mode 100644 index 00000000..19c27265 --- /dev/null +++ b/frontend/src/assets/images/settingsIcon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/components/layout/header/Header.styled.ts b/frontend/src/components/layout/header/Header.styled.ts new file mode 100644 index 00000000..25fae278 --- /dev/null +++ b/frontend/src/components/layout/header/Header.styled.ts @@ -0,0 +1,12 @@ +import { css } from '@emotion/react'; + +export const headerLayout = css` + display: flex; + justify-content: space-between; + align-items: center; +`; + +export const gameTitle = css` + font-weight: bold; + font-size: 1.6rem; +`; diff --git a/frontend/src/components/layout/header/Header.tsx b/frontend/src/components/layout/header/Header.tsx new file mode 100644 index 00000000..6c79eaaa --- /dev/null +++ b/frontend/src/components/layout/header/Header.tsx @@ -0,0 +1,24 @@ +import { gameTitle, headerLayout } from './Header.styled'; + +import HomeIcon from '@/assets/images/homeIcon.svg'; +import SettingsIcon from '@/assets/images/settingsIcon.svg'; + +interface HeaderProps { + title: string; +} + +const Header = ({ title }: HeaderProps) => { + return ( +
+ + {title} + +
+ ); +}; + +export default Header; From 4e326c2892fbf27ed59f6d89dbdefc35d1fd309d Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 16 Jul 2024 06:00:31 +0900 Subject: [PATCH 0043/1013] =?UTF-8?q?design:=20button=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84=20#7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/commmon/button/Button.styled.ts | 13 +++++++++++++ .../src/components/commmon/button/Button.tsx | 17 +++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 frontend/src/components/commmon/button/Button.styled.ts create mode 100644 frontend/src/components/commmon/button/Button.tsx diff --git a/frontend/src/components/commmon/button/Button.styled.ts b/frontend/src/components/commmon/button/Button.styled.ts new file mode 100644 index 00000000..3c36a91d --- /dev/null +++ b/frontend/src/components/commmon/button/Button.styled.ts @@ -0,0 +1,13 @@ +import { css } from '@emotion/react'; + +import { Theme } from '@/styles/Theme'; + +export const buttonLayout = (active: boolean) => css` + padding: 1rem 4rem; + + background-color: ${active ? Theme.color.peanut500 : Theme.color.peanut300}; + + font-weight: bold; + font-size: 2rem; + border-radius: 2.4rem; +`; diff --git a/frontend/src/components/commmon/button/Button.tsx b/frontend/src/components/commmon/button/Button.tsx new file mode 100644 index 00000000..804ec087 --- /dev/null +++ b/frontend/src/components/commmon/button/Button.tsx @@ -0,0 +1,17 @@ +import { buttonLayout } from './Button.styled'; + +interface ButtonProps { + text: '선택' | '확인' | '다음'; + active: boolean; + onClick: () => void; +} + +const Button = ({ text, active, onClick }: ButtonProps) => { + return ( + + ); +}; + +export default Button; From 68d11af5b8713da2101121ac6b88201ab9b8d3da Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 16 Jul 2024 06:01:42 +0900 Subject: [PATCH 0044/1013] =?UTF-8?q?design:=20=EA=B8=80=EB=A1=9C=EB=B2=8C?= =?UTF-8?q?=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=B6=94=EA=B0=80=20#7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/styles/GlobalStyle.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/frontend/src/styles/GlobalStyle.ts b/frontend/src/styles/GlobalStyle.ts index 7761966b..22f4de84 100644 --- a/frontend/src/styles/GlobalStyle.ts +++ b/frontend/src/styles/GlobalStyle.ts @@ -130,12 +130,20 @@ const reset = css` border-collapse: collapse; border-spacing: 0; } + + button { + border: none; + outline: none; + background-color: inherit; + cursor: pointer; + } `; const GlobalStyle = css` ${reset} html { + margin-top: 3rem; font-size: 10px; } From d9b891c5958e0327b6f5b441c8613d82920c7394 Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 16 Jul 2024 06:22:12 +0900 Subject: [PATCH 0045/1013] =?UTF-8?q?design:=20TopicContainer=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84=20#7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../topicContainer/TopicContainer.styled.ts | 18 ++++++++++++++++++ .../topicContainer/TopicContainer.tsx | 17 +++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 frontend/src/components/topicContainer/TopicContainer.styled.ts create mode 100644 frontend/src/components/topicContainer/TopicContainer.tsx diff --git a/frontend/src/components/topicContainer/TopicContainer.styled.ts b/frontend/src/components/topicContainer/TopicContainer.styled.ts new file mode 100644 index 00000000..c88fe907 --- /dev/null +++ b/frontend/src/components/topicContainer/TopicContainer.styled.ts @@ -0,0 +1,18 @@ +import { css } from '@emotion/react'; + +export const topicLayout = css` + display: flex; + flex-direction: column; + align-items: center; + gap: 1.4rem; +`; + +export const categoryText = css` + font-weight: bold; + font-size: 1.4rem; +`; + +export const topicText = css` + font-weight: bold; + font-size: 2rem; +`; diff --git a/frontend/src/components/topicContainer/TopicContainer.tsx b/frontend/src/components/topicContainer/TopicContainer.tsx new file mode 100644 index 00000000..28490b01 --- /dev/null +++ b/frontend/src/components/topicContainer/TopicContainer.tsx @@ -0,0 +1,17 @@ +import { categoryText, topicLayout, topicText } from './TopicContainer.styled'; + +interface TopicContainerProp { + category: string; + title: string; +} + +const TopicContainer = ({ category, title }: TopicContainerProp) => { + return ( +
+ {category} + {title} +
+ ); +}; + +export default TopicContainer; From 11071cdf844f55c8010a0d75e9044de94e170a05 Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 16 Jul 2024 07:27:16 +0900 Subject: [PATCH 0046/1013] =?UTF-8?q?refactor:=20=ED=8F=B4=EB=8D=94=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?#7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/{commmon => common}/button/Button.styled.ts | 0 frontend/src/components/{commmon => common}/button/Button.tsx | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename frontend/src/components/{commmon => common}/button/Button.styled.ts (100%) rename frontend/src/components/{commmon => common}/button/Button.tsx (100%) diff --git a/frontend/src/components/commmon/button/Button.styled.ts b/frontend/src/components/common/button/Button.styled.ts similarity index 100% rename from frontend/src/components/commmon/button/Button.styled.ts rename to frontend/src/components/common/button/Button.styled.ts diff --git a/frontend/src/components/commmon/button/Button.tsx b/frontend/src/components/common/button/Button.tsx similarity index 100% rename from frontend/src/components/commmon/button/Button.tsx rename to frontend/src/components/common/button/Button.tsx From 3a070e42cb025289d41b8f92d99d973008dd1d94 Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 16 Jul 2024 07:58:08 +0900 Subject: [PATCH 0047/1013] =?UTF-8?q?refactor:=20=EC=86=8C=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=EB=AA=85=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?#7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/common/button/Button.styled.ts | 13 ---------- .../src/components/common/button/Button.tsx | 17 ------------- .../components/layout/header/Header.styled.ts | 12 ---------- .../src/components/layout/header/Header.tsx | 24 ------------------- .../topicContainer/TopicContainer.styled.ts | 18 -------------- .../topicContainer/TopicContainer.tsx | 17 ------------- 6 files changed, 101 deletions(-) delete mode 100644 frontend/src/components/common/button/Button.styled.ts delete mode 100644 frontend/src/components/common/button/Button.tsx delete mode 100644 frontend/src/components/layout/header/Header.styled.ts delete mode 100644 frontend/src/components/layout/header/Header.tsx delete mode 100644 frontend/src/components/topicContainer/TopicContainer.styled.ts delete mode 100644 frontend/src/components/topicContainer/TopicContainer.tsx diff --git a/frontend/src/components/common/button/Button.styled.ts b/frontend/src/components/common/button/Button.styled.ts deleted file mode 100644 index 3c36a91d..00000000 --- a/frontend/src/components/common/button/Button.styled.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { css } from '@emotion/react'; - -import { Theme } from '@/styles/Theme'; - -export const buttonLayout = (active: boolean) => css` - padding: 1rem 4rem; - - background-color: ${active ? Theme.color.peanut500 : Theme.color.peanut300}; - - font-weight: bold; - font-size: 2rem; - border-radius: 2.4rem; -`; diff --git a/frontend/src/components/common/button/Button.tsx b/frontend/src/components/common/button/Button.tsx deleted file mode 100644 index 804ec087..00000000 --- a/frontend/src/components/common/button/Button.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { buttonLayout } from './Button.styled'; - -interface ButtonProps { - text: '선택' | '확인' | '다음'; - active: boolean; - onClick: () => void; -} - -const Button = ({ text, active, onClick }: ButtonProps) => { - return ( - - ); -}; - -export default Button; diff --git a/frontend/src/components/layout/header/Header.styled.ts b/frontend/src/components/layout/header/Header.styled.ts deleted file mode 100644 index 25fae278..00000000 --- a/frontend/src/components/layout/header/Header.styled.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { css } from '@emotion/react'; - -export const headerLayout = css` - display: flex; - justify-content: space-between; - align-items: center; -`; - -export const gameTitle = css` - font-weight: bold; - font-size: 1.6rem; -`; diff --git a/frontend/src/components/layout/header/Header.tsx b/frontend/src/components/layout/header/Header.tsx deleted file mode 100644 index 6c79eaaa..00000000 --- a/frontend/src/components/layout/header/Header.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { gameTitle, headerLayout } from './Header.styled'; - -import HomeIcon from '@/assets/images/homeIcon.svg'; -import SettingsIcon from '@/assets/images/settingsIcon.svg'; - -interface HeaderProps { - title: string; -} - -const Header = ({ title }: HeaderProps) => { - return ( -
- - {title} - -
- ); -}; - -export default Header; diff --git a/frontend/src/components/topicContainer/TopicContainer.styled.ts b/frontend/src/components/topicContainer/TopicContainer.styled.ts deleted file mode 100644 index c88fe907..00000000 --- a/frontend/src/components/topicContainer/TopicContainer.styled.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { css } from '@emotion/react'; - -export const topicLayout = css` - display: flex; - flex-direction: column; - align-items: center; - gap: 1.4rem; -`; - -export const categoryText = css` - font-weight: bold; - font-size: 1.4rem; -`; - -export const topicText = css` - font-weight: bold; - font-size: 2rem; -`; diff --git a/frontend/src/components/topicContainer/TopicContainer.tsx b/frontend/src/components/topicContainer/TopicContainer.tsx deleted file mode 100644 index 28490b01..00000000 --- a/frontend/src/components/topicContainer/TopicContainer.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { categoryText, topicLayout, topicText } from './TopicContainer.styled'; - -interface TopicContainerProp { - category: string; - title: string; -} - -const TopicContainer = ({ category, title }: TopicContainerProp) => { - return ( -
- {category} - {title} -
- ); -}; - -export default TopicContainer; From 482f722fea9d055fd4ce6368f3985fed5ef98f99 Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 16 Jul 2024 08:05:56 +0900 Subject: [PATCH 0048/1013] =?UTF-8?q?refactor:=20=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=EB=AA=85=20=EB=8C=80=EB=AC=B8=EC=9E=90=EB=A1=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20#7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/App.tsx | 8 +++---- .../src/components/GameResult/GameResult.tsx | 2 +- .../SelectContainer/SelectContainer.tsx | 2 +- .../TopicContainer/TopicContainer.styled.ts | 18 +++++++++++++++ .../TopicContainer/TopicContainer.tsx | 17 ++++++++++++++ .../components/common/Button/Button.styled.ts | 14 ++++++----- .../src/components/common/Button/Button.tsx | 16 ++++++++++--- .../components/layout/Header/Header.styled.ts | 12 ++++++++++ .../src/components/layout/Header/Header.tsx | 23 +++++++++++++++++++ frontend/src/pages/GamePage/GamePage.tsx | 15 ++++++++++++ 10 files changed, 111 insertions(+), 16 deletions(-) create mode 100644 frontend/src/components/TopicContainer/TopicContainer.styled.ts create mode 100644 frontend/src/components/TopicContainer/TopicContainer.tsx create mode 100644 frontend/src/components/layout/Header/Header.styled.ts create mode 100644 frontend/src/components/layout/Header/Header.tsx create mode 100644 frontend/src/pages/GamePage/GamePage.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 360521c5..658dce01 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,9 +1,7 @@ +import GamePage from './pages/GamePage/GamePage'; + const App = () => { - return ( -
-

ddang-kong

-
- ); + return ; }; export default App; diff --git a/frontend/src/components/GameResult/GameResult.tsx b/frontend/src/components/GameResult/GameResult.tsx index d7f3e803..12d435be 100644 --- a/frontend/src/components/GameResult/GameResult.tsx +++ b/frontend/src/components/GameResult/GameResult.tsx @@ -6,7 +6,7 @@ const GameResult = () => { return (

게임 결과

-
); }; diff --git a/frontend/src/components/SelectContainer/SelectContainer.tsx b/frontend/src/components/SelectContainer/SelectContainer.tsx index 3bff1b3e..7879fe0f 100644 --- a/frontend/src/components/SelectContainer/SelectContainer.tsx +++ b/frontend/src/components/SelectContainer/SelectContainer.tsx @@ -11,7 +11,7 @@ const SelectContainer = () => { VS - ; +interface ButtonProps { + text: '선택' | '확인' | '다음'; + active: boolean; + onClick: () => void; +} + +const Button = ({ text, active, onClick }: ButtonProps) => { + return ( + + ); }; export default Button; diff --git a/frontend/src/components/layout/Header/Header.styled.ts b/frontend/src/components/layout/Header/Header.styled.ts new file mode 100644 index 00000000..25fae278 --- /dev/null +++ b/frontend/src/components/layout/Header/Header.styled.ts @@ -0,0 +1,12 @@ +import { css } from '@emotion/react'; + +export const headerLayout = css` + display: flex; + justify-content: space-between; + align-items: center; +`; + +export const gameTitle = css` + font-weight: bold; + font-size: 1.6rem; +`; diff --git a/frontend/src/components/layout/Header/Header.tsx b/frontend/src/components/layout/Header/Header.tsx new file mode 100644 index 00000000..1e6f3553 --- /dev/null +++ b/frontend/src/components/layout/Header/Header.tsx @@ -0,0 +1,23 @@ +import HomeIcon from '@/assets/images/homeIcon.svg'; +import SettingsIcon from '@/assets/images/settingsIcon.svg'; +import { gameTitle, headerLayout } from './Header.styled'; + +interface HeaderProps { + title: string; +} + +const Header = ({ title }: HeaderProps) => { + return ( +
+ + {title} + +
+ ); +}; + +export default Header; diff --git a/frontend/src/pages/GamePage/GamePage.tsx b/frontend/src/pages/GamePage/GamePage.tsx new file mode 100644 index 00000000..200b24ca --- /dev/null +++ b/frontend/src/pages/GamePage/GamePage.tsx @@ -0,0 +1,15 @@ +import Button from '@/components/common/Button/Button'; +import Header from '@/components/layout/Header/Header'; +import TopicContainer from '@/components/TopicContainer/TopicContainer'; + +const GamePage = () => { + return ( + <> +
+ + {title} diff --git a/frontend/src/pages/RoundResultPage/RoundResultPage.tsx b/frontend/src/pages/RoundResultPage/RoundResultPage.tsx new file mode 100644 index 00000000..6edb46fa --- /dev/null +++ b/frontend/src/pages/RoundResultPage/RoundResultPage.tsx @@ -0,0 +1,30 @@ +import { useNavigate } from 'react-router-dom'; + +import { NicknameListWrapper } from './RoundResultPage.styled'; + +import Button from '@/components/common/Button/Button'; +import Content from '@/components/layout/Content/Content'; +import NicknameList from '@/components/NicknameList/NicknameList'; +import RoundVoteResult from '@/components/RoundVoteResult/RoundVoteResult'; +import TopicContainer from '@/components/TopicContainer/TopicContainer'; + +const RoundResultPage = () => { + const navigate = useNavigate(); + + const goToGameResult = () => { + navigate('/game-result'); + }; + + return ( + + + +
+ +
+ + ); }; export default SelectOption; From 280d2ef812ee711167bac2e239e7e7930c042b3a Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Tue, 16 Jul 2024 13:06:02 +0900 Subject: [PATCH 0067/1013] =?UTF-8?q?feat:=20=EA=B3=B5=ED=86=B5=20Header?= =?UTF-8?q?=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B3=B5=EC=9A=A9?= =?UTF-8?q?=ED=99=94=20#11?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Yuseon Kim(썬데이) Co-authored-by: novice0840 --- frontend/src/router/index.tsx | 3 +++ frontend/src/router/layout.tsx | 12 ++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 frontend/src/router/layout.tsx diff --git a/frontend/src/router/index.tsx b/frontend/src/router/index.tsx index 48785f98..056d3fe7 100644 --- a/frontend/src/router/index.tsx +++ b/frontend/src/router/index.tsx @@ -1,5 +1,7 @@ import { createBrowserRouter } from 'react-router-dom'; +import { Layout } from './layout'; + import GamePage from '@/pages/GamePage/GamePage'; import GameResultPage from '@/pages/GameResultPage/GameResultPage'; import RoundResultPage from '@/pages/RoundResultPage/RoundResultPage'; @@ -7,6 +9,7 @@ import RoundResultPage from '@/pages/RoundResultPage/RoundResultPage'; export const router = createBrowserRouter([ { path: '/', + element: , children: [ { index: true, diff --git a/frontend/src/router/layout.tsx b/frontend/src/router/layout.tsx new file mode 100644 index 00000000..ba15424b --- /dev/null +++ b/frontend/src/router/layout.tsx @@ -0,0 +1,12 @@ +import { Outlet } from 'react-router-dom'; + +import Header from '@/components/layout/Header/Header'; + +export const Layout = () => { + return ( + <> +
+ + + ); +}; From e9c6c85c59cf0ecee9b2453207e11c9bfb53e584 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Tue, 16 Jul 2024 13:54:17 +0900 Subject: [PATCH 0068/1013] =?UTF-8?q?build:=20plain=20jar=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=83=9D=EC=84=B1=20=EB=B0=A9=EC=A7=80=20#18?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/build.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/build.gradle b/backend/build.gradle index a3cac280..0a1b9a39 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -14,6 +14,10 @@ java { } } +jar { + enabled = false +} + configurations { compileOnly { extendsFrom annotationProcessor From 53aaaa40d9ed9a59e97e5edce8bc489debf6a725 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Wed, 17 Jul 2024 17:43:12 +0900 Subject: [PATCH 0069/1013] =?UTF-8?q?chore:=20BE=20CI=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=BD=ED=8A=B8=20=EC=9E=91=EC=84=B1=20#18?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/.github/workflows/be-ci-dev.yml | 30 +++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 backend/.github/workflows/be-ci-dev.yml diff --git a/backend/.github/workflows/be-ci-dev.yml b/backend/.github/workflows/be-ci-dev.yml new file mode 100644 index 00000000..b73c1810 --- /dev/null +++ b/backend/.github/workflows/be-ci-dev.yml @@ -0,0 +1,30 @@ +name: BE CI for Dev + +on: + pull_request: + branches: [ "develop" ] + paths: + - backend/** + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: checkout + uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Build with Gradle + run: ./gradlew clean build From c4bb36161b79be22cee37b952f404709fc095e6b Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Wed, 17 Jul 2024 17:43:22 +0900 Subject: [PATCH 0070/1013] =?UTF-8?q?chore:=20BE=20CD=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=BD=ED=8A=B8=20=EC=9E=91=EC=84=B1=20#18?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/.github/workflows/be-cd-dev.yml | 47 +++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 backend/.github/workflows/be-cd-dev.yml diff --git a/backend/.github/workflows/be-cd-dev.yml b/backend/.github/workflows/be-cd-dev.yml new file mode 100644 index 00000000..1c27a3e0 --- /dev/null +++ b/backend/.github/workflows/be-cd-dev.yml @@ -0,0 +1,47 @@ +name: BE CI for Dev + +on: + pull_request: + branches: [ "develop" ] + paths: + - backend/** + +permissions: + contents: read + +jobs: +# # docker 이동 시, 사용 +# build: +# runs-on: ubuntu-latest +# +# steps: +# - name: checkout +# uses: actions/checkout@v4 +# +# - name: Set up JDK 17 +# uses: actions/setup-java@v4 +# with: +# java-version: '17' +# distribution: 'temurin' +# +# - name: Grant execute permission for gradlew +# run: chmod +x gradlew +# +# - name: Build with Gradle +# run: ./gradlew clean bootJar + + deploy: +# needs: build + runs-on: [self-hosted, linux, ARM64] + + # EC2에 배포 + # EC2 SSH 키를 private_key.pem 파일로 저장 ( 위치는 GitHub 서버 ) + # SSH를 사용하여 EC2 서버에 연결하고 현재 실행 중인 Java 프로세스를 종료한 다음 새로운 Java 프로세스 생성 및 실행!! + ## NLP 적용하면 IP -> 도메인으로 수정 + EC2 늘리면 run 추가 + steps: + - name: Deploy to EC2 + run: | + echo "${{ secrets.EC2_DEV_SSH_KEY }}" > private_key.pem + chmod 600 private_key.pem + ssh -i private_key.pem ${{ secrets.EC2_DEV_USERNAME }}@${{ secrets.EC2_DEV_IP }} | sh deploy-script-dev.sh + rm -f private_key.pem From ec82c9d3396536b4a49d73a9aa442f23c8135db5 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Wed, 17 Jul 2024 17:50:54 +0900 Subject: [PATCH 0071/1013] =?UTF-8?q?refactor:=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=BD=ED=8A=B8=20name=20=EC=98=A4=EB=A5=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20=EC=82=AC=EC=9A=A9=ED=95=98=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EB=8A=94=20=EC=A3=BC=EC=84=9D=20=EC=A0=9C=EA=B1=B0=20?= =?UTF-8?q?#18?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/.github/workflows/be-cd-dev.yml | 29 ++----------------------- 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/backend/.github/workflows/be-cd-dev.yml b/backend/.github/workflows/be-cd-dev.yml index 1c27a3e0..b65844fe 100644 --- a/backend/.github/workflows/be-cd-dev.yml +++ b/backend/.github/workflows/be-cd-dev.yml @@ -1,4 +1,4 @@ -name: BE CI for Dev +name: BE CD for Dev on: pull_request: @@ -10,34 +10,9 @@ permissions: contents: read jobs: -# # docker 이동 시, 사용 -# build: -# runs-on: ubuntu-latest -# -# steps: -# - name: checkout -# uses: actions/checkout@v4 -# -# - name: Set up JDK 17 -# uses: actions/setup-java@v4 -# with: -# java-version: '17' -# distribution: 'temurin' -# -# - name: Grant execute permission for gradlew -# run: chmod +x gradlew -# -# - name: Build with Gradle -# run: ./gradlew clean bootJar - deploy: -# needs: build - runs-on: [self-hosted, linux, ARM64] + runs-on: [self-hosted, linux, ARM64] # Self hosted runner 사용 - # EC2에 배포 - # EC2 SSH 키를 private_key.pem 파일로 저장 ( 위치는 GitHub 서버 ) - # SSH를 사용하여 EC2 서버에 연결하고 현재 실행 중인 Java 프로세스를 종료한 다음 새로운 Java 프로세스 생성 및 실행!! - ## NLP 적용하면 IP -> 도메인으로 수정 + EC2 늘리면 run 추가 steps: - name: Deploy to EC2 run: | From 96bf38f5bbed3a8e0a7bdb352719eac5e30ade57 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Wed, 17 Jul 2024 17:57:11 +0900 Subject: [PATCH 0072/1013] =?UTF-8?q?fix:=20cd=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=BD=ED=8A=B8=20=EB=8F=99=EC=9E=91=20=EC=8B=9C=EC=A0=90=20?= =?UTF-8?q?PR=20->=20Push=20=EC=8B=9C=EC=A0=90=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20#22?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/.github/workflows/be-cd-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/.github/workflows/be-cd-dev.yml b/backend/.github/workflows/be-cd-dev.yml index b65844fe..30aaa9d3 100644 --- a/backend/.github/workflows/be-cd-dev.yml +++ b/backend/.github/workflows/be-cd-dev.yml @@ -1,7 +1,7 @@ name: BE CD for Dev on: - pull_request: + push: branches: [ "develop" ] paths: - backend/** From d9cba32f15949a32e400f033c4205c8e353f0997 Mon Sep 17 00:00:00 2001 From: Eden <84304802+PgmJun@users.noreply.github.com> Date: Wed, 17 Jul 2024 18:09:54 +0900 Subject: [PATCH 0073/1013] =?UTF-8?q?refactor:=20CD=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=BD=ED=8A=B8=20=EC=9C=84=EC=B9=98=20=EC=B5=9C=EC=83=81?= =?UTF-8?q?=EC=9C=84=EB=A1=9C=20=EC=88=98=EC=A0=95=20#22?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- {backend/.github => .github}/workflows/be-cd-dev.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {backend/.github => .github}/workflows/be-cd-dev.yml (100%) diff --git a/backend/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml similarity index 100% rename from backend/.github/workflows/be-cd-dev.yml rename to .github/workflows/be-cd-dev.yml From 588d43d555ed3e3b04e77258ed0ffabd06debe6d Mon Sep 17 00:00:00 2001 From: Eden <84304802+PgmJun@users.noreply.github.com> Date: Wed, 17 Jul 2024 18:10:41 +0900 Subject: [PATCH 0074/1013] =?UTF-8?q?refactor:=20CI=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=BD=ED=8A=B8=20=EC=9C=84=EC=B9=98=20=EC=B5=9C=EC=83=81?= =?UTF-8?q?=EC=9C=84=EB=A1=9C=20=EC=88=98=EC=A0=95=20#22?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- {backend/.github => .github}/workflows/be-ci-dev.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {backend/.github => .github}/workflows/be-ci-dev.yml (100%) diff --git a/backend/.github/workflows/be-ci-dev.yml b/.github/workflows/be-ci-dev.yml similarity index 100% rename from backend/.github/workflows/be-ci-dev.yml rename to .github/workflows/be-ci-dev.yml From 6409fe58ef20a48d807aa1e56b8b7560d9dd5385 Mon Sep 17 00:00:00 2001 From: Eden <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 09:28:32 +0900 Subject: [PATCH 0075/1013] =?UTF-8?q?fix:=20=EC=8A=A4=ED=81=AC=EB=A6=BD?= =?UTF-8?q?=ED=8A=B8=20=ED=8C=A8=ED=82=A4=EC=A7=80=20=EB=B3=80=EA=B2=BD?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=A5=B8=20gradlew=20=EC=9C=84=EC=B9=98?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=20#22?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-ci-dev.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/be-ci-dev.yml b/.github/workflows/be-ci-dev.yml index b73c1810..df991186 100644 --- a/.github/workflows/be-ci-dev.yml +++ b/.github/workflows/be-ci-dev.yml @@ -24,7 +24,7 @@ jobs: distribution: 'temurin' - name: Grant execute permission for gradlew - run: chmod +x gradlew + run: chmod +x backend/gradlew - name: Build with Gradle - run: ./gradlew clean build + run: ./backend/gradlew clean build From c46c26829b389dd5f3072c2d192c2fc62ff4e3ed Mon Sep 17 00:00:00 2001 From: Eden <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 09:35:26 +0900 Subject: [PATCH 0076/1013] =?UTF-8?q?fix:=20working=20directory=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20#22?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-ci-dev.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/be-ci-dev.yml b/.github/workflows/be-ci-dev.yml index df991186..580c0f95 100644 --- a/.github/workflows/be-ci-dev.yml +++ b/.github/workflows/be-ci-dev.yml @@ -13,6 +13,11 @@ jobs: build: runs-on: ubuntu-latest + defaults: + run: + shell: bash + working-directory: ./backend + steps: - name: checkout uses: actions/checkout@v4 @@ -24,7 +29,7 @@ jobs: distribution: 'temurin' - name: Grant execute permission for gradlew - run: chmod +x backend/gradlew + run: chmod +x gradlew - name: Build with Gradle - run: ./backend/gradlew clean build + run: ./gradlew clean build From 5e05ba2f279db4d9b6c44fa39cefa5bb2c906e1a Mon Sep 17 00:00:00 2001 From: Eden <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 10:53:18 +0900 Subject: [PATCH 0077/1013] =?UTF-8?q?fix:=20CD=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=BD=ED=8A=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - deploy sh 파일 실행 코드 오류 수정 - StrictHostKeyChecking=no 설정을 통해 호스트 키 체킹 과정 생략 --- .github/workflows/be-cd-dev.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 30aaa9d3..87aa0846 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -14,9 +14,18 @@ jobs: runs-on: [self-hosted, linux, ARM64] # Self hosted runner 사용 steps: - - name: Deploy to EC2 + - name: Checkout code + uses: actions/checkout@v2 + + - name: Setup SSH key run: | echo "${{ secrets.EC2_DEV_SSH_KEY }}" > private_key.pem chmod 600 private_key.pem - ssh -i private_key.pem ${{ secrets.EC2_DEV_USERNAME }}@${{ secrets.EC2_DEV_IP }} | sh deploy-script-dev.sh + + - name: Deploy to EC2 + run: | + ssh -i private_key.pem -o StrictHostKeyChecking=no ${{ secrets.EC2_DEV_USERNAME }}@${{ secrets.EC2_DEV_IP }} sh ~/deploy-script-dev.sh + + - name: Cleanup + run: | rm -f private_key.pem From 72cacedcb9804189b48fffed80f5f8d883cd2cae Mon Sep 17 00:00:00 2001 From: Eden <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 11:01:03 +0900 Subject: [PATCH 0078/1013] =?UTF-8?q?refactor:=20checkout=20=EB=B2=84?= =?UTF-8?q?=EC=A0=84=20v2=20->=20v4=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20#22?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 87aa0846..7c929858 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup SSH key run: | From dee2460c07b47decd01792d25f4299a98a5c213e Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 17 Jul 2024 16:49:10 +0900 Subject: [PATCH 0079/1013] =?UTF-8?q?style:=20import=EB=AC=B8=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ddangkong/controller/exception/ErrorResponse.java | 8 +++----- .../controller/exception/GlobalExceptionHandler.java | 1 - 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/backend/src/main/java/ddangkong/controller/exception/ErrorResponse.java b/backend/src/main/java/ddangkong/controller/exception/ErrorResponse.java index e2e26d95..ce7a0dd3 100644 --- a/backend/src/main/java/ddangkong/controller/exception/ErrorResponse.java +++ b/backend/src/main/java/ddangkong/controller/exception/ErrorResponse.java @@ -1,15 +1,13 @@ package ddangkong.controller.exception; +import static com.fasterxml.jackson.annotation.JsonInclude.Include; + import com.fasterxml.jackson.annotation.JsonInclude; import jakarta.validation.ConstraintViolation; import jakarta.validation.Path; -import jakarta.validation.constraints.NotEmpty; -import org.springframework.validation.BindingResult; - import java.util.List; import java.util.Set; - -import static com.fasterxml.jackson.annotation.JsonInclude.Include; +import org.springframework.validation.BindingResult; public record ErrorResponse( String message, diff --git a/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java b/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java index 554be21a..0d2c4df6 100644 --- a/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java +++ b/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java @@ -3,7 +3,6 @@ import jakarta.validation.ConstraintViolationException; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; import org.springframework.validation.BindException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; From 71db0ecc546413c6af6ae2c52d79886b30521daf Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 17 Jul 2024 16:51:33 +0900 Subject: [PATCH 0080/1013] =?UTF-8?q?feat:=20ERD=EC=97=90=20=EB=94=B0?= =?UTF-8?q?=EB=A5=B8=20Entity=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ddangkong/domain/member/Member.java | 34 ++++++++++++++++++ .../domain/option/BalanceOption.java | 34 ++++++++++++++++++ .../domain/question/BalanceQuestion.java | 33 +++++++++++++++++ .../ddangkong/domain/question/Category.java | 4 +++ .../main/java/ddangkong/domain/room/Room.java | 23 ++++++++++++ .../ddangkong/domain/room/RoomQuestion.java | 34 ++++++++++++++++++ .../ddangkong/domain/vote/BalanceVote.java | 36 +++++++++++++++++++ 7 files changed, 198 insertions(+) create mode 100644 backend/src/main/java/ddangkong/domain/member/Member.java create mode 100644 backend/src/main/java/ddangkong/domain/option/BalanceOption.java create mode 100644 backend/src/main/java/ddangkong/domain/question/BalanceQuestion.java create mode 100644 backend/src/main/java/ddangkong/domain/question/Category.java create mode 100644 backend/src/main/java/ddangkong/domain/room/Room.java create mode 100644 backend/src/main/java/ddangkong/domain/room/RoomQuestion.java create mode 100644 backend/src/main/java/ddangkong/domain/vote/BalanceVote.java diff --git a/backend/src/main/java/ddangkong/domain/member/Member.java b/backend/src/main/java/ddangkong/domain/member/Member.java new file mode 100644 index 00000000..98e7f702 --- /dev/null +++ b/backend/src/main/java/ddangkong/domain/member/Member.java @@ -0,0 +1,34 @@ +package ddangkong.domain.member; + +import ddangkong.domain.room.Room; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +@EqualsAndHashCode +@ToString +public class Member { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String nickname; + + @ManyToOne(optional = false) + @JoinColumn(name = "room_id", nullable = false) + private Room room; +} diff --git a/backend/src/main/java/ddangkong/domain/option/BalanceOption.java b/backend/src/main/java/ddangkong/domain/option/BalanceOption.java new file mode 100644 index 00000000..69b9f075 --- /dev/null +++ b/backend/src/main/java/ddangkong/domain/option/BalanceOption.java @@ -0,0 +1,34 @@ +package ddangkong.domain.option; + +import ddangkong.domain.question.BalanceQuestion; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +@EqualsAndHashCode +@ToString +public class BalanceOption { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String content; + + @ManyToOne(optional = false) + @JoinColumn(name = "balance_question_id", nullable = false) + private BalanceQuestion balanceQuestion; +} diff --git a/backend/src/main/java/ddangkong/domain/question/BalanceQuestion.java b/backend/src/main/java/ddangkong/domain/question/BalanceQuestion.java new file mode 100644 index 00000000..20205a73 --- /dev/null +++ b/backend/src/main/java/ddangkong/domain/question/BalanceQuestion.java @@ -0,0 +1,33 @@ +package ddangkong.domain.question; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +@EqualsAndHashCode +@ToString +public class BalanceQuestion { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Enumerated(EnumType.STRING) + @Column(nullable = false) + private Category category; + + @Column(nullable = false) + private String content; +} diff --git a/backend/src/main/java/ddangkong/domain/question/Category.java b/backend/src/main/java/ddangkong/domain/question/Category.java new file mode 100644 index 00000000..afa5689b --- /dev/null +++ b/backend/src/main/java/ddangkong/domain/question/Category.java @@ -0,0 +1,4 @@ +package ddangkong.domain.question; + +public enum Category { +} diff --git a/backend/src/main/java/ddangkong/domain/room/Room.java b/backend/src/main/java/ddangkong/domain/room/Room.java new file mode 100644 index 00000000..77f0cb12 --- /dev/null +++ b/backend/src/main/java/ddangkong/domain/room/Room.java @@ -0,0 +1,23 @@ +package ddangkong.domain.room; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +@EqualsAndHashCode +@ToString +public class Room { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; +} diff --git a/backend/src/main/java/ddangkong/domain/room/RoomQuestion.java b/backend/src/main/java/ddangkong/domain/room/RoomQuestion.java new file mode 100644 index 00000000..7011ef27 --- /dev/null +++ b/backend/src/main/java/ddangkong/domain/room/RoomQuestion.java @@ -0,0 +1,34 @@ +package ddangkong.domain.room; + +import ddangkong.domain.question.BalanceQuestion; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +@EqualsAndHashCode +@ToString +public class RoomQuestion { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(optional = false) + @JoinColumn(name = "room_id") + private Room room; + + @ManyToOne(optional = false) + @JoinColumn(name = "balance_question_id") + private BalanceQuestion balanceQuestion; +} diff --git a/backend/src/main/java/ddangkong/domain/vote/BalanceVote.java b/backend/src/main/java/ddangkong/domain/vote/BalanceVote.java new file mode 100644 index 00000000..620c9fde --- /dev/null +++ b/backend/src/main/java/ddangkong/domain/vote/BalanceVote.java @@ -0,0 +1,36 @@ +package ddangkong.domain.vote; + +import ddangkong.domain.member.Member; +import ddangkong.domain.option.BalanceOption; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +@EqualsAndHashCode +@ToString +public class BalanceVote { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(optional = false) + @JoinColumn(name = "balance_option_id", nullable = false) + private BalanceOption balanceOption; + + @ManyToOne(optional = false) + @JoinColumn(name = "member_id", nullable = false) + private Member member; + +} From 2270ed5e020c40c2a998b801581b76068b181cab Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 17 Jul 2024 17:18:40 +0900 Subject: [PATCH 0081/1013] =?UTF-8?q?fix:=20=EC=A0=95=EC=83=81=EC=A0=81?= =?UTF-8?q?=EC=9D=B8=20=EC=8A=A4=ED=82=A4=EB=A7=88=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=B4,=20enum=EC=97=90=20=EC=98=88?= =?UTF-8?q?=EC=8B=9C=20=EA=B0=92=20=ED=95=98=EB=82=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/main/java/ddangkong/domain/question/Category.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backend/src/main/java/ddangkong/domain/question/Category.java b/backend/src/main/java/ddangkong/domain/question/Category.java index afa5689b..fe67d4c5 100644 --- a/backend/src/main/java/ddangkong/domain/question/Category.java +++ b/backend/src/main/java/ddangkong/domain/question/Category.java @@ -1,4 +1,6 @@ package ddangkong.domain.question; public enum Category { + EXAMPLE, + ; } From 2d58a9a2bf766c9da0ef9fbbca6553a954928bf5 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 18 Jul 2024 12:34:33 +0900 Subject: [PATCH 0082/1013] =?UTF-8?q?fix:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=ED=99=98=EA=B2=BD=EC=97=90=EC=84=9C=20H2=20SQL=EC=9D=84=20?= =?UTF-8?q?=EC=9D=B4=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/test/resources/application.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/src/test/resources/application.yml b/backend/src/test/resources/application.yml index cbee9fe9..fbca624a 100644 --- a/backend/src/test/resources/application.yml +++ b/backend/src/test/resources/application.yml @@ -1,13 +1,13 @@ spring: - active: - profiles: test + profiles: + active: test jpa: properties: hibernate: format_sql: true highlight_sql: true show_sql: true - database-platform: org.hibernate.dialect.MySQL8Dialect + database-platform: org.hibernate.dialect.H2Dialect --- spring: @@ -16,7 +16,7 @@ spring: on-profile: test datasource: driver-class-name: org.h2.Driver - url: jdbc:h2:mem:testdb;MODE=MYSQL;DB_CLOSE_DELAY=-1 + url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1 username: sa h2: console: From 7bc6f8d95be04eabaa1e4e5ade5cf1604eb45b96 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 18 Jul 2024 13:40:56 +0900 Subject: [PATCH 0083/1013] =?UTF-8?q?feat:=20Entity=EB=A5=BC=20Lazy=20Load?= =?UTF-8?q?ing=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/main/java/ddangkong/domain/member/Member.java | 3 ++- .../main/java/ddangkong/domain/option/BalanceOption.java | 3 ++- .../src/main/java/ddangkong/domain/room/RoomQuestion.java | 5 +++-- .../src/main/java/ddangkong/domain/vote/BalanceVote.java | 6 +++--- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/member/Member.java b/backend/src/main/java/ddangkong/domain/member/Member.java index 98e7f702..6cd46d46 100644 --- a/backend/src/main/java/ddangkong/domain/member/Member.java +++ b/backend/src/main/java/ddangkong/domain/member/Member.java @@ -3,6 +3,7 @@ import ddangkong.domain.room.Room; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; @@ -28,7 +29,7 @@ public class Member { @Column(nullable = false) private String nickname; - @ManyToOne(optional = false) + @ManyToOne(optional = false, fetch = FetchType.LAZY) @JoinColumn(name = "room_id", nullable = false) private Room room; } diff --git a/backend/src/main/java/ddangkong/domain/option/BalanceOption.java b/backend/src/main/java/ddangkong/domain/option/BalanceOption.java index 69b9f075..a109ce4f 100644 --- a/backend/src/main/java/ddangkong/domain/option/BalanceOption.java +++ b/backend/src/main/java/ddangkong/domain/option/BalanceOption.java @@ -3,6 +3,7 @@ import ddangkong.domain.question.BalanceQuestion; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; @@ -28,7 +29,7 @@ public class BalanceOption { @Column(nullable = false) private String content; - @ManyToOne(optional = false) + @ManyToOne(optional = false, fetch = FetchType.LAZY) @JoinColumn(name = "balance_question_id", nullable = false) private BalanceQuestion balanceQuestion; } diff --git a/backend/src/main/java/ddangkong/domain/room/RoomQuestion.java b/backend/src/main/java/ddangkong/domain/room/RoomQuestion.java index 7011ef27..5972d879 100644 --- a/backend/src/main/java/ddangkong/domain/room/RoomQuestion.java +++ b/backend/src/main/java/ddangkong/domain/room/RoomQuestion.java @@ -2,6 +2,7 @@ import ddangkong.domain.question.BalanceQuestion; import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; @@ -24,11 +25,11 @@ public class RoomQuestion { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @ManyToOne(optional = false) + @ManyToOne(optional = false, fetch = FetchType.LAZY) @JoinColumn(name = "room_id") private Room room; - @ManyToOne(optional = false) + @ManyToOne(optional = false, fetch = FetchType.LAZY) @JoinColumn(name = "balance_question_id") private BalanceQuestion balanceQuestion; } diff --git a/backend/src/main/java/ddangkong/domain/vote/BalanceVote.java b/backend/src/main/java/ddangkong/domain/vote/BalanceVote.java index 620c9fde..08f8c85f 100644 --- a/backend/src/main/java/ddangkong/domain/vote/BalanceVote.java +++ b/backend/src/main/java/ddangkong/domain/vote/BalanceVote.java @@ -3,6 +3,7 @@ import ddangkong.domain.member.Member; import ddangkong.domain.option.BalanceOption; import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; @@ -25,12 +26,11 @@ public class BalanceVote { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @ManyToOne(optional = false) + @ManyToOne(optional = false, fetch = FetchType.LAZY) @JoinColumn(name = "balance_option_id", nullable = false) private BalanceOption balanceOption; - @ManyToOne(optional = false) + @ManyToOne(optional = false, fetch = FetchType.LAZY) @JoinColumn(name = "member_id", nullable = false) private Member member; - } From 0d7396097eff579ebab8da35e184ed1e4441317f Mon Sep 17 00:00:00 2001 From: Eden <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 14:12:01 +0900 Subject: [PATCH 0084/1013] =?UTF-8?q?fix:=20deploy=20script=20=EC=8B=A4?= =?UTF-8?q?=ED=96=89=20=EC=BD=94=EB=93=9C=20self-hosted=20=EB=B0=A9?= =?UTF-8?q?=EC=8B=9D=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20#22?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 7c929858..bbc05a74 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -13,19 +13,5 @@ jobs: deploy: runs-on: [self-hosted, linux, ARM64] # Self hosted runner 사용 - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup SSH key - run: | - echo "${{ secrets.EC2_DEV_SSH_KEY }}" > private_key.pem - chmod 600 private_key.pem - - name: Deploy to EC2 - run: | - ssh -i private_key.pem -o StrictHostKeyChecking=no ${{ secrets.EC2_DEV_USERNAME }}@${{ secrets.EC2_DEV_IP }} sh ~/deploy-script-dev.sh - - - name: Cleanup - run: | - rm -f private_key.pem + run: sudo sh ~/deploy-script-dev.sh From b7636a3b7504f77df050925731c8126268a7921a Mon Sep 17 00:00:00 2001 From: Eden <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 14:23:51 +0900 Subject: [PATCH 0085/1013] =?UTF-8?q?fix:=20job=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=BD=ED=8A=B8=20=EB=82=B4=EB=B6=80=EC=97=90=20steps=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#22?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index bbc05a74..b00121de 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -12,6 +12,6 @@ permissions: jobs: deploy: runs-on: [self-hosted, linux, ARM64] # Self hosted runner 사용 - - - name: Deploy to EC2 + steps: + - name: Execute script on EC2 to deploy run: sudo sh ~/deploy-script-dev.sh From 84ccecf6e22b279adf1e4f06057d108e33488e96 Mon Sep 17 00:00:00 2001 From: Eden <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 14:42:36 +0900 Subject: [PATCH 0086/1013] =?UTF-8?q?feat:=20workflow=5Fdispatch=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20#31?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 ++ .github/workflows/be-ci-dev.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index b00121de..2c1337df 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -1,6 +1,8 @@ name: BE CD for Dev on: + workflow_dispatch: + push: branches: [ "develop" ] paths: diff --git a/.github/workflows/be-ci-dev.yml b/.github/workflows/be-ci-dev.yml index 580c0f95..dfad31e4 100644 --- a/.github/workflows/be-ci-dev.yml +++ b/.github/workflows/be-ci-dev.yml @@ -1,6 +1,8 @@ name: BE CI for Dev on: + workflow_dispatch: + pull_request: branches: [ "develop" ] paths: From 1cd7e0fb782a8bb1e2557858b4fd19bfeb523bd1 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 18 Jul 2024 00:07:14 +0900 Subject: [PATCH 0087/1013] =?UTF-8?q?design:=20=EC=84=A0=ED=83=9D=ED=95=9C?= =?UTF-8?q?=20=EC=98=B5=EC=85=98=EC=9D=84=20=EA=B0=95=EC=A1=B0=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EC=95=A0=EB=8B=88=EB=A9=94=EC=9D=B4=EC=85=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#25?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/SelectOption/SelectOption.styled.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/src/components/SelectOption/SelectOption.styled.ts b/frontend/src/components/SelectOption/SelectOption.styled.ts index a7c2d77c..a49b9f7a 100644 --- a/frontend/src/components/SelectOption/SelectOption.styled.ts +++ b/frontend/src/components/SelectOption/SelectOption.styled.ts @@ -20,4 +20,7 @@ export const layout = (selected: boolean) => css` word-break: keep-all; border-radius: 3rem; /* 둥근 모서리 */ + + transition: all 0.5s; + scale: ${selected ? 1.1 : 1}; `; From a72cd8040aec46acf27ceba4c885dd38ab1fc6e6 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 18 Jul 2024 00:19:50 +0900 Subject: [PATCH 0088/1013] =?UTF-8?q?build:=20msw=EC=99=80=20jest=EB=A5=BC?= =?UTF-8?q?=20=EC=97=B0=EB=8F=99=ED=95=98=EA=B8=B0=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?undici=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=84=A4=EC=B9=98=20#25?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/package-lock.json | 1814 ++++++++++-------------------------- frontend/package.json | 1 + 2 files changed, 471 insertions(+), 1344 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 862797cc..c502529e 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -26,7 +26,6 @@ "@storybook/addon-interactions": "^8.2.2", "@storybook/addon-links": "^8.2.2", "@storybook/addon-onboarding": "^8.2.2", - "@storybook/addon-themes": "^8.2.3", "@storybook/addon-webpack5-compiler-swc": "^1.0.4", "@storybook/blocks": "^8.2.2", "@storybook/react": "^8.2.2", @@ -69,10 +68,14 @@ "stylelint-order": "^6.0.4", "ts-loader": "^9.5.1", "typescript": "^5.5.3", + "undici": "^5.28.4", "webpack": "^5.92.1", "webpack-cli": "^5.1.4", "webpack-dev-server": "^5.0.4", "webpack-merge": "^6.0.1" + }, + "engines": { + "node": "18.x" } }, "node_modules/@adobe/css-tools": { @@ -689,9 +692,8 @@ }, "node_modules/@babel/plugin-syntax-flow": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.24.7.tgz", - "integrity": "sha512-9G8GYT/dxn/D1IIKOUBmGX0mnmj46mGH9NnZyJLwtCpgh5f7D2VbuKodb+2s9m1Yavh1s7ASQN8lf0eqrb1LTw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -1121,9 +1123,8 @@ }, "node_modules/@babel/plugin-transform-flow-strip-types": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.24.7.tgz", - "integrity": "sha512-cjRKJ7FobOH2eakx7Ja+KpJRj8+y+/SiB3ooYm/n2UJfxu0oEaOoxOinitkJcPqv9KxS0kxTGPUaR7L2XcXDXA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", "@babel/plugin-syntax-flow": "^7.24.7" @@ -1802,9 +1803,8 @@ }, "node_modules/@babel/preset-flow": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.24.7.tgz", - "integrity": "sha512-NL3Lo0NorCU607zU3NwRyJbpaB6E3t0xtd3LfAQKDfkeX4/ggcDXvkmkW42QWT5owUeW/jAe4hn+2qvkV1IbfQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", "@babel/helper-validator-option": "^7.24.7", @@ -1869,9 +1869,8 @@ }, "node_modules/@babel/register": { "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.24.6.tgz", - "integrity": "sha512-WSuFCc2wCqMeXkz/i3yfAAsxwWflEgbVkZzivgAmXl/MxrXeoYFZOOPllbC8R8WTF7u61wSRQtDVZ1879cdu6w==", "dev": true, + "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", "find-cache-dir": "^2.0.0", @@ -1888,9 +1887,8 @@ }, "node_modules/@babel/register/node_modules/find-cache-dir": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "dev": true, + "license": "MIT", "dependencies": { "commondir": "^1.0.1", "make-dir": "^2.0.0", @@ -1902,9 +1900,8 @@ }, "node_modules/@babel/register/node_modules/find-up": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^3.0.0" }, @@ -1914,9 +1911,8 @@ }, "node_modules/@babel/register/node_modules/locate-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -1927,9 +1923,8 @@ }, "node_modules/@babel/register/node_modules/p-locate": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.0.0" }, @@ -1939,18 +1934,16 @@ }, "node_modules/@babel/register/node_modules/path-exists": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/register/node_modules/pkg-dir": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^3.0.0" }, @@ -2018,9 +2011,8 @@ }, "node_modules/@base2/pretty-print-object": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz", - "integrity": "sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA==", - "dev": true + "dev": true, + "license": "BSD-2-Clause" }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", @@ -2053,9 +2045,8 @@ }, "node_modules/@chromatic-com/storybook": { "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@chromatic-com/storybook/-/storybook-1.6.1.tgz", - "integrity": "sha512-x1x1NB3j4xpfeSWKr96emc+7ZvfsvH+/WVb3XCjkB24PPbT8VZXb3mJSAQMrSzuQ8+eQE9kDogYHH9Fj3tb/Cw==", "dev": true, + "license": "MIT", "dependencies": { "chromatic": "^11.4.0", "filesize": "^10.0.12", @@ -2070,9 +2061,8 @@ }, "node_modules/@chromatic-com/storybook/node_modules/ansi-regex": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -2082,9 +2072,8 @@ }, "node_modules/@chromatic-com/storybook/node_modules/strip-ansi": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -2097,8 +2086,6 @@ }, "node_modules/@csstools/css-parser-algorithms": { "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.7.1.tgz", - "integrity": "sha512-2SJS42gxmACHgikc1WGesXLIT8d/q2l0UFM7TaEeIzdFCE/FPMtTiizcPGGJtlPo2xuQzY09OhrLTzRxqJqwGw==", "dev": true, "funding": [ { @@ -2110,6 +2097,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT", "engines": { "node": "^14 || ^16 || >=18" }, @@ -2119,8 +2107,6 @@ }, "node_modules/@csstools/css-tokenizer": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.4.1.tgz", - "integrity": "sha512-eQ9DIktFJBhGjioABJRtUucoWR2mwllurfnM8LuNGAqX3ViZXaUchqk+1s7jjtkFiT9ySdACsFEA3etErkALUg==", "dev": true, "funding": [ { @@ -2132,14 +2118,13 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT", "engines": { "node": "^14 || ^16 || >=18" } }, "node_modules/@csstools/media-query-list-parser": { "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.13.tgz", - "integrity": "sha512-XaHr+16KRU9Gf8XLi3q8kDlI18d5vzKSKCY510Vrtc9iNR0NJzbY9hhTmwhzYZj/ZwGL4VmB3TA9hJW0Um2qFA==", "dev": true, "funding": [ { @@ -2151,6 +2136,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT", "engines": { "node": "^14 || ^16 || >=18" }, @@ -2161,8 +2147,6 @@ }, "node_modules/@csstools/selector-specificity": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.1.1.tgz", - "integrity": "sha512-a7cxGcJ2wIlMFLlh8z2ONm+715QkPHiyJcxwQlKOz/03GPw1COpfhcmC9wm4xlZfp//jWHNNMwzjtqHXVWU9KA==", "dev": true, "funding": [ { @@ -2174,6 +2158,7 @@ "url": "https://opencollective.com/csstools" } ], + "license": "MIT-0", "engines": { "node": "^14 || ^16 || >=18" }, @@ -2191,9 +2176,8 @@ }, "node_modules/@dual-bundle/import-meta-resolve": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", - "integrity": "sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -2312,78 +2296,13 @@ "version": "0.3.1", "license": "MIT" }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@esbuild/darwin-arm64": { "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -2392,294 +2311,6 @@ "node": ">=12" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "dev": true, @@ -2766,6 +2397,15 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "dev": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "dev": true, @@ -3818,9 +3458,8 @@ }, "node_modules/@mdx-js/react": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.0.1.tgz", - "integrity": "sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A==", "dev": true, + "license": "MIT", "dependencies": { "@types/mdx": "^2.0.0" }, @@ -3925,8 +3564,7 @@ }, "node_modules/@remix-run/router": { "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.17.1.tgz", - "integrity": "sha512-mCOMec4BKd6BRGBZeSnGiIgwsbLGp3yhVqAD8H+PxiRNEHgDpZb8J1TnrSDlg97t0ySKMQJTHCWBCmBpSmkF6Q==", + "license": "MIT", "engines": { "node": ">=14.0.0" } @@ -3938,9 +3576,8 @@ }, "node_modules/@sindresorhus/merge-streams": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", - "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -3966,9 +3603,8 @@ }, "node_modules/@storybook/addon-actions": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.2.2.tgz", - "integrity": "sha512-SN4cSRt3f0qXi5te+yhMseSdQuZntA8lGlASbRmN77YQTpIaGsNiH88xFoky0s9qz531hiRfU1R0ZSMylBwSKw==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", "@types/uuid": "^9.0.1", @@ -3986,22 +3622,20 @@ }, "node_modules/@storybook/addon-actions/node_modules/uuid": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "dev": true, "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/@storybook/addon-backgrounds": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.2.2.tgz", - "integrity": "sha512-m/xJe7uKL+kfJx7pQcHwAeIvJ3tdLIpDGrMAVDNDJHcAxfe44cFjIInaV/1HKf3y5Awap+DZFW66ekkxuI9zzA==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", "memoizerific": "^1.11.3", @@ -4017,9 +3651,8 @@ }, "node_modules/@storybook/addon-controls": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.2.2.tgz", - "integrity": "sha512-y241aOANGzT5XBADUIvALwG/xF5eC6UItzmWJaFvOzSBCq74GIA0+Hu9atyFdvFQbXOrdvPWC4jR+9iuBFRxAA==", "dev": true, + "license": "MIT", "dependencies": { "dequal": "^2.0.2", "lodash": "^4.17.21", @@ -4035,9 +3668,8 @@ }, "node_modules/@storybook/addon-docs": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.2.2.tgz", - "integrity": "sha512-qk/yjAR9RpsSrKLLbeCgb6u58c8TmYqyJSnXgbAozZZNKHBWlIpvZ/hTNYud8qo0coPlxnLdjnZf32TykWGlAg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.24.4", "@mdx-js/react": "^3.0.0", @@ -4063,9 +3695,8 @@ }, "node_modules/@storybook/addon-docs/node_modules/fs-extra": { "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -4077,9 +3708,8 @@ }, "node_modules/@storybook/addon-essentials": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.2.2.tgz", - "integrity": "sha512-yN//BFMbSvNV0+Sll2hcKmgJX06TUKQDm6pZimUjkXczFtOmK7K/UdDmKjWS+qjhfJdWpxdRoEpxoHvvRmNfsA==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/addon-actions": "8.2.2", "@storybook/addon-backgrounds": "8.2.2", @@ -4102,9 +3732,8 @@ }, "node_modules/@storybook/addon-highlight": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.2.2.tgz", - "integrity": "sha512-yDTRzzL+IJAymgY32xoZl09BGBVmPOUV2wVNGYcZkkBLvz2GSQMTfUe1/7F4jAx//+rFBu48/MQzsTC7Bk8kPw==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0" }, @@ -4118,9 +3747,8 @@ }, "node_modules/@storybook/addon-interactions": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.2.2.tgz", - "integrity": "sha512-zRRuUwm/l41JtTUgjIoQTUgLT99Hsdz9cqKca/8NYo1MGBdEcKE41DH4aBIzKaOKFu7p9q00/o/X1EqYX4LMUA==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", "@storybook/instrumenter": "8.2.2", @@ -4138,9 +3766,8 @@ }, "node_modules/@storybook/addon-links": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-8.2.2.tgz", - "integrity": "sha512-eGh7O7SgTJMtnuXC0HlRPOegu1njcJS2cnVqjbzjvjxsPSBhbHpdYMi9Q9E7al/FKuqMUOjIR9YLIlmK1AJaqA==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/csf": "0.1.11", "@storybook/global": "^5.0.0", @@ -4162,9 +3789,8 @@ }, "node_modules/@storybook/addon-measure": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.2.2.tgz", - "integrity": "sha512-3rCo/aMltt5FrBVdr2dYlD8HlE2q9TLKGJZnwh9on4QyL6ArHbdYw0LmyHe/LrFahJ49w1XQZBMSJcAdRkkS7w==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", "tiny-invariant": "^1.3.1" @@ -4179,9 +3805,8 @@ }, "node_modules/@storybook/addon-onboarding": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/addon-onboarding/-/addon-onboarding-8.2.2.tgz", - "integrity": "sha512-dCdE8Mt/JW6cq6dY7co35Sul/bAkUT3ixaxBrUagFUYUQ/PTYM6p4/B+45RURD5S9z8LVHH1rVgmEeScm3U78w==", "dev": true, + "license": "MIT", "dependencies": { "react-confetti": "^6.1.0" }, @@ -4195,9 +3820,8 @@ }, "node_modules/@storybook/addon-outline": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.2.2.tgz", - "integrity": "sha512-Y+PQtfTNO8GLX5nz+3x5AMfHNvdGvBXazJ29+Rl1ygYN1+Q9ZhRJDE1kAK0wLxb7CG14peAgdYEaQb3Rduv7HQ==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", "ts-dedent": "^2.0.0" @@ -4210,27 +3834,10 @@ "storybook": "^8.2.2" } }, - "node_modules/@storybook/addon-themes": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-themes/-/addon-themes-8.2.3.tgz", - "integrity": "sha512-0Be9zEvhAGCEt0+z+XL09EkclHhrKCNX1GbKO40HiFlJTzWDDBJb6wyY8V4dFq4eU/144zQOdC9DHlXS7WSMRw==", - "dev": true, - "dependencies": { - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "^8.2.3" - } - }, "node_modules/@storybook/addon-toolbars": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.2.2.tgz", - "integrity": "sha512-JGOueOc3EPljlCl9dVSQee0aMYoqGNvN0UH+R6wYJ3bDZ+tUG/iYpsZVPUOvS8vzp3Imk5Is1kzQbQYJtzdGLg==", "dev": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" @@ -4241,9 +3848,8 @@ }, "node_modules/@storybook/addon-viewport": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.2.2.tgz", - "integrity": "sha512-gkZ8bsjGGP0NuevkT2iKC+szezSy+w4BrBDknf490mRU2K/B2e7TGojf/j/AtxzILMzD4IKzKUXbE/zwcqjZvA==", "dev": true, + "license": "MIT", "dependencies": { "memoizerific": "^1.11.3" }, @@ -4257,9 +3863,8 @@ }, "node_modules/@storybook/addon-webpack5-compiler-swc": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-webpack5-compiler-swc/-/addon-webpack5-compiler-swc-1.0.4.tgz", - "integrity": "sha512-S/ypdAK9oqwUAt3ZOn44qi3RWdH5uBLbBgtfHSXckqTpQRu7F7A9bRzjK+H5ti4xVADRhxu/xzIBwxWgcCeIXA==", "dev": true, + "license": "MIT", "dependencies": { "@swc/core": "1.5.7", "swc-loader": "^0.2.3" @@ -4270,9 +3875,8 @@ }, "node_modules/@storybook/blocks": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.2.2.tgz", - "integrity": "sha512-av0Tryg4toDl2L/d1ABErtsAk9wvM1su6+M4wq5/Go50sk5IjGTldhbZFa9zNOohxLkZwaj0Q5xAgJ1Y+m5KrQ==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/csf": "0.1.11", "@storybook/global": "^5.0.0", @@ -4309,9 +3913,8 @@ }, "node_modules/@storybook/blocks/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, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -4321,15 +3924,13 @@ }, "node_modules/@storybook/blocks/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 + "dev": true, + "license": "MIT" }, "node_modules/@storybook/builder-webpack5": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-8.2.2.tgz", - "integrity": "sha512-ud6a3pRusbC/TvT1ed15INxSivyL2y2zI61O/MWQZmM8sZOIC6ObdHLtzU4+535IIqiXhPoQ/QiOBbejqjgZvw==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/core-webpack": "8.2.2", "@types/node": "^18.0.0", @@ -4374,18 +3975,16 @@ }, "node_modules/@storybook/builder-webpack5/node_modules/@types/node": { "version": "18.19.39", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz", - "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==", "dev": true, + "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@storybook/builder-webpack5/node_modules/ajv": { "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -4399,9 +3998,8 @@ }, "node_modules/@storybook/builder-webpack5/node_modules/ajv-keywords": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -4411,9 +4009,8 @@ }, "node_modules/@storybook/builder-webpack5/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, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -4426,9 +4023,8 @@ }, "node_modules/@storybook/builder-webpack5/node_modules/brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4436,9 +4032,8 @@ }, "node_modules/@storybook/builder-webpack5/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4452,9 +4047,8 @@ }, "node_modules/@storybook/builder-webpack5/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, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -4464,15 +4058,13 @@ }, "node_modules/@storybook/builder-webpack5/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 + "dev": true, + "license": "MIT" }, "node_modules/@storybook/builder-webpack5/node_modules/fork-ts-checker-webpack-plugin": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-8.0.0.tgz", - "integrity": "sha512-mX3qW3idpueT2klaQXBzrIM/pHw+T0B/V9KHEvNrqijTq9NFnMZU6oreVxDYcf33P8a5cW+67PjodNHthGnNVg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.16.7", "chalk": "^4.1.2", @@ -4498,9 +4090,8 @@ }, "node_modules/@storybook/builder-webpack5/node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -4512,9 +4103,8 @@ }, "node_modules/@storybook/builder-webpack5/node_modules/fs-extra": { "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -4526,15 +4116,13 @@ }, "node_modules/@storybook/builder-webpack5/node_modules/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==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@storybook/builder-webpack5/node_modules/memfs": { "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, + "license": "Unlicense", "dependencies": { "fs-monkey": "^1.0.4" }, @@ -4544,9 +4132,8 @@ }, "node_modules/@storybook/builder-webpack5/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -4556,9 +4143,8 @@ }, "node_modules/@storybook/builder-webpack5/node_modules/semver": { "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -4568,9 +4154,8 @@ }, "node_modules/@storybook/builder-webpack5/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, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -4580,9 +4165,8 @@ }, "node_modules/@storybook/builder-webpack5/node_modules/webpack-dev-middleware": { "version": "6.1.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.1.3.tgz", - "integrity": "sha512-A4ChP0Qj8oGociTs6UdlRUGANIGrCDL3y+pmQMc+dSsraXHCatFpmMey4mYELA+juqwUqwQsUgJJISXl1KWmiw==", "dev": true, + "license": "MIT", "dependencies": { "colorette": "^2.0.10", "memfs": "^3.4.12", @@ -4608,9 +4192,8 @@ }, "node_modules/@storybook/builder-webpack5/node_modules/webpack-dev-middleware/node_modules/schema-utils": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -4627,9 +4210,8 @@ }, "node_modules/@storybook/codemod": { "version": "8.2.3", - "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-8.2.3.tgz", - "integrity": "sha512-mAc22OJthMr1oaGVKRbO05sveTUhcWhdgN4nQKf7wLfXjW73mMgrblao+mxiWIfhXIjbOB5xgw3Csi9pcy6Kkw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.24.4", "@babel/preset-env": "^7.24.4", @@ -4652,9 +4234,8 @@ }, "node_modules/@storybook/codemod/node_modules/globby": { "version": "14.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", - "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", "dev": true, + "license": "MIT", "dependencies": { "@sindresorhus/merge-streams": "^2.1.0", "fast-glob": "^3.3.2", @@ -4672,9 +4253,8 @@ }, "node_modules/@storybook/codemod/node_modules/path-type": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", - "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -4684,9 +4264,8 @@ }, "node_modules/@storybook/codemod/node_modules/slash": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.16" }, @@ -4696,9 +4275,8 @@ }, "node_modules/@storybook/core": { "version": "8.2.3", - "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.2.3.tgz", - "integrity": "sha512-6CV6P8ES7E+vQZEuJTdLhgC3Lo7iRy+tpc/3przT25EStzNTR3TW2X31KUn7BfY2fuxCFPzftPaSJ/LEi7zHqg==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/csf": "0.1.11", "@types/express": "^4.17.21", @@ -4719,9 +4297,8 @@ }, "node_modules/@storybook/core-webpack": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-8.2.2.tgz", - "integrity": "sha512-M5wzgNbotVXcfo7WkXIuDxcBl7tTjnQ27lmlSBk+cu63pDvNn4UMDan621FcvxWq2DbjgIj+PASZ4DzM5O+ovA==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "^18.0.0", "ts-dedent": "^2.0.0" @@ -4736,36 +4313,32 @@ }, "node_modules/@storybook/core-webpack/node_modules/@types/node": { "version": "18.19.39", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz", - "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==", "dev": true, + "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@storybook/core/node_modules/@types/node": { "version": "18.19.39", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz", - "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==", "dev": true, + "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@storybook/csf": { "version": "0.1.11", - "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.1.11.tgz", - "integrity": "sha512-dHYFQH3mA+EtnCkHXzicbLgsvzYjcDJ1JWsogbItZogkPHgSJM/Wr71uMkcvw8v9mmCyP4NpXJuu6bPoVsOnzg==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^2.19.0" } }, "node_modules/@storybook/csf-plugin": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.2.2.tgz", - "integrity": "sha512-3K2RUpDDvq3DT46qAIj2VBC+fzTTebRUcZUsRfS6G1AzaX9p25iClEHiwcJacFkgQKhkci8A/Ly3Z4JJ3b4Pgw==", "dev": true, + "license": "MIT", "dependencies": { "unplugin": "^1.3.1" }, @@ -4779,9 +4352,8 @@ }, "node_modules/@storybook/csf/node_modules/type-fest": { "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=12.20" }, @@ -4791,15 +4363,13 @@ }, "node_modules/@storybook/global": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@storybook/global/-/global-5.0.0.tgz", - "integrity": "sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@storybook/icons": { "version": "1.2.9", - "resolved": "https://registry.npmjs.org/@storybook/icons/-/icons-1.2.9.tgz", - "integrity": "sha512-cOmylsz25SYXaJL/gvTk/dl3pyk7yBFRfeXTsHvTA3dfhoU/LWSq0NKL9nM7WBasJyn6XPSGnLS4RtKXLw5EUg==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.0.0" }, @@ -4810,9 +4380,8 @@ }, "node_modules/@storybook/instrumenter": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.2.2.tgz", - "integrity": "sha512-refwnHqKHhya45MgqakhMG0jKhTiEIAl0aOwAaQy9+zf9ncMIYQAXRQsSZ2Z188lFWE24wbeHKteb62a5ZfWwQ==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", "@vitest/utils": "^1.3.1", @@ -4828,9 +4397,8 @@ }, "node_modules/@storybook/preset-react-webpack": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/preset-react-webpack/-/preset-react-webpack-8.2.2.tgz", - "integrity": "sha512-GJkDtw4Ac8icD66fotGXYE3rmZkIwASpNLOeGzyP4eMMNaf5vlvTDxwkY551cGbnA5P7r4UkGjDiWinB9XE4VQ==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/core-webpack": "8.2.2", "@storybook/react": "8.2.2", @@ -4866,18 +4434,16 @@ }, "node_modules/@storybook/preset-react-webpack/node_modules/@types/node": { "version": "18.19.39", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz", - "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==", "dev": true, + "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@storybook/preset-react-webpack/node_modules/find-up": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -4891,9 +4457,8 @@ }, "node_modules/@storybook/preset-react-webpack/node_modules/fs-extra": { "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -4905,9 +4470,8 @@ }, "node_modules/@storybook/preset-react-webpack/node_modules/locate-path": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -4920,9 +4484,8 @@ }, "node_modules/@storybook/preset-react-webpack/node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -4935,9 +4498,8 @@ }, "node_modules/@storybook/preset-react-webpack/node_modules/p-locate": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -4950,9 +4512,8 @@ }, "node_modules/@storybook/preset-react-webpack/node_modules/semver": { "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -4962,9 +4523,8 @@ }, "node_modules/@storybook/preset-react-webpack/node_modules/tsconfig-paths": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", - "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", "dev": true, + "license": "MIT", "dependencies": { "json5": "^2.2.2", "minimist": "^1.2.6", @@ -4976,9 +4536,8 @@ }, "node_modules/@storybook/preset-react-webpack/node_modules/yocto-queue": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4988,9 +4547,8 @@ }, "node_modules/@storybook/react": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.2.2.tgz", - "integrity": "sha512-U4p/RV78yhjEwEzem8U7wE5/3sSpnqreGsPdAHMCIHd69e9tVeF0rwrTJGp917RClPjBKgEcfelCuvOlby4MrA==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", "@storybook/react-dom-shim": "8.2.2", @@ -5031,9 +4589,8 @@ }, "node_modules/@storybook/react-docgen-typescript-plugin": { "version": "1.0.6--canary.9.0c3f3b7.0", - "resolved": "https://registry.npmjs.org/@storybook/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.6--canary.9.0c3f3b7.0.tgz", - "integrity": "sha512-KUqXC3oa9JuQ0kZJLBhVdS4lOneKTOopnNBK4tUAgoxWQ3u/IjzdueZjFr7gyBrXMoU6duutk3RQR9u8ZpYJ4Q==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.1.1", "endent": "^2.0.1", @@ -5050,9 +4607,8 @@ }, "node_modules/@storybook/react-docgen-typescript-plugin/node_modules/find-cache-dir": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, + "license": "MIT", "dependencies": { "commondir": "^1.0.1", "make-dir": "^3.0.2", @@ -5067,9 +4623,8 @@ }, "node_modules/@storybook/react-docgen-typescript-plugin/node_modules/make-dir": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, + "license": "MIT", "dependencies": { "semver": "^6.0.0" }, @@ -5082,9 +4637,8 @@ }, "node_modules/@storybook/react-dom-shim": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.2.2.tgz", - "integrity": "sha512-4fb1/yT9WXHzHjs0In6orIEZxga5eXd9UaXEFGudBgowCjDUVP9LabDdKTbGusz20lfaAkATsRG/W+EcSLoh8w==", "dev": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" @@ -5097,9 +4651,8 @@ }, "node_modules/@storybook/react-webpack5": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/react-webpack5/-/react-webpack5-8.2.2.tgz", - "integrity": "sha512-JPR2Lp88KbfRWgnAd4lKFRKuc9Up6YeqbaDb6sptOXXzDM4nOhlRXKqp2tIqyhfiKp3wmu3PksixqD8f8VS9CA==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/builder-webpack5": "8.2.2", "@storybook/preset-react-webpack": "8.2.2", @@ -5127,33 +4680,29 @@ }, "node_modules/@storybook/react-webpack5/node_modules/@types/node": { "version": "18.19.39", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz", - "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==", "dev": true, + "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@storybook/react/node_modules/@types/estree": { "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@storybook/react/node_modules/@types/node": { "version": "18.19.39", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz", - "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==", "dev": true, + "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@storybook/react/node_modules/acorn": { "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -5163,18 +4712,16 @@ }, "node_modules/@storybook/react/node_modules/acorn-walk": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/@storybook/react/node_modules/semver": { "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -5184,9 +4731,8 @@ }, "node_modules/@storybook/react/node_modules/type-fest": { "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=12.20" }, @@ -5196,9 +4742,8 @@ }, "node_modules/@storybook/test": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.2.2.tgz", - "integrity": "sha512-X2qAKErjTh1X7XLAZqCMtU0ZK8JuwdKmgiqU0oXWxIDmCX6/Dm9ZIcdMZHs/S+K/UnIByjNlQpTShLVfRUeN1w==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/csf": "0.1.11", "@storybook/instrumenter": "8.2.2", @@ -5219,9 +4764,8 @@ }, "node_modules/@storybook/test/node_modules/@testing-library/dom": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.1.0.tgz", - "integrity": "sha512-wdsYKy5zupPyLCW2Je5DLHSxSfbIp6h80WoHOQc+RPtmPGA52O9x5MJEkv92Sjonpq+poOAtUKhh1kBGAXBrNA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -5238,9 +4782,8 @@ }, "node_modules/@storybook/test/node_modules/@testing-library/jest-dom": { "version": "6.4.5", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.5.tgz", - "integrity": "sha512-AguB9yvTXmCnySBP1lWjfNNUwpbElsaQ567lt2VdGqAdHtpieLgjmcVyv1q7PMIvLbgpDdkWV5Ydv3FEejyp2A==", "dev": true, + "license": "MIT", "dependencies": { "@adobe/css-tools": "^4.3.2", "@babel/runtime": "^7.9.2", @@ -5283,9 +4826,8 @@ }, "node_modules/@storybook/test/node_modules/@testing-library/jest-dom/node_modules/chalk": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -5296,15 +4838,13 @@ }, "node_modules/@storybook/test/node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { "version": "0.6.3", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", - "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@storybook/test/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, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -5317,18 +4857,16 @@ }, "node_modules/@storybook/test/node_modules/aria-query": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, + "license": "Apache-2.0", "dependencies": { "dequal": "^2.0.3" } }, "node_modules/@storybook/test/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -5342,9 +4880,8 @@ }, "node_modules/@storybook/test/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, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -5354,15 +4891,13 @@ }, "node_modules/@storybook/test/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 + "dev": true, + "license": "MIT" }, "node_modules/@storybook/test/node_modules/pretty-format": { "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -5374,9 +4909,8 @@ }, "node_modules/@storybook/test/node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -5386,15 +4920,13 @@ }, "node_modules/@storybook/test/node_modules/react-is": { "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@storybook/test/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, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -5404,10 +4936,9 @@ }, "node_modules/@swc/core": { "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.5.7.tgz", - "integrity": "sha512-U4qJRBefIJNJDRCCiVtkfa/hpiZ7w0R6kASea+/KLp+vkus3zcLSB8Ub8SvKgTIxjWpwsKcZlPf5nrv4ls46SQ==", "dev": true, "hasInstallScript": true, + "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.2", "@swc/types": "0.1.7" @@ -5442,12 +4973,11 @@ }, "node_modules/@swc/core-darwin-arm64": { "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.5.7.tgz", - "integrity": "sha512-bZLVHPTpH3h6yhwVl395k0Mtx8v6CGhq5r4KQdAoPbADU974Mauz1b6ViHAJ74O0IVE5vyy7tD3OpkQxL/vMDQ==", "cpu": [ "arm64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "darwin" @@ -5456,170 +4986,23 @@ "node": ">=10" } }, - "node_modules/@swc/core-darwin-x64": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.5.7.tgz", - "integrity": "sha512-RpUyu2GsviwTc2qVajPL0l8nf2vKj5wzO3WkLSHAHEJbiUZk83NJrZd1RVbEknIMO7+Uyjh54hEh8R26jSByaw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.5.7.tgz", - "integrity": "sha512-cTZWTnCXLABOuvWiv6nQQM0hP6ZWEkzdgDvztgHI/+u/MvtzJBN5lBQ2lue/9sSFYLMqzqff5EHKlFtrJCA9dQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.5.7.tgz", - "integrity": "sha512-hoeTJFBiE/IJP30Be7djWF8Q5KVgkbDtjySmvYLg9P94bHg9TJPSQoC72tXx/oXOgXvElDe/GMybru0UxhKx4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.5.7.tgz", - "integrity": "sha512-+NDhK+IFTiVK1/o7EXdCeF2hEzCiaRSrb9zD7X2Z7inwWlxAntcSuzZW7Y6BRqGQH89KA91qYgwbnjgTQ22PiQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.5.7.tgz", - "integrity": "sha512-25GXpJmeFxKB+7pbY7YQLhWWjkYlR+kHz5I3j9WRl3Lp4v4UD67OGXwPe+DIcHqcouA1fhLhsgHJWtsaNOMBNg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-x64-musl": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.5.7.tgz", - "integrity": "sha512-0VN9Y5EAPBESmSPPsCJzplZHV26akC0sIgd3Hc/7S/1GkSMoeuVL+V9vt+F/cCuzr4VidzSkqftdP3qEIsXSpg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.5.7.tgz", - "integrity": "sha512-RtoNnstBwy5VloNCvmvYNApkTmuCe4sNcoYWpmY7C1+bPR+6SOo8im1G6/FpNem8AR5fcZCmXHWQ+EUmRWJyuA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.5.7.tgz", - "integrity": "sha512-Xm0TfvcmmspvQg1s4+USL3x8D+YPAfX2JHygvxAnCJ0EHun8cm2zvfNBcsTlnwYb0ybFWXXY129aq1wgFC9TpQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.5.7.tgz", - "integrity": "sha512-tp43WfJLCsKLQKBmjmY/0vv1slVywR5Q4qKjF5OIY8QijaEW7/8VwPyUyVoJZEnDgv9jKtUTG5PzqtIYPZGnyg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, "node_modules/@swc/counter": { "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", - "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/@swc/types": { "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.7.tgz", - "integrity": "sha512-scHWahbHF0eyj3JsxG9CFJgFdFNaVQCNAimBlT6PzS3n/HptxqREjsm4OH6AN3lYcffZYSPxXW8ua2BEHp0lJQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.3" } }, "node_modules/@tanstack/eslint-plugin-query": { "version": "5.51.1", - "resolved": "https://registry.npmjs.org/@tanstack/eslint-plugin-query/-/eslint-plugin-query-5.51.1.tgz", - "integrity": "sha512-M1IBJTtD9V69Zf4Efnkizg+DKdn4yTt+OfD0my5hZRok4wPZ44+Y8XNUFpwy6nsEV/Qt+KsS8IWPjd+eERQUSA==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/utils": "8.0.0-alpha.30" }, @@ -5633,9 +5016,8 @@ }, "node_modules/@tanstack/eslint-plugin-query/node_modules/@typescript-eslint/scope-manager": { "version": "8.0.0-alpha.30", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.0.0-alpha.30.tgz", - "integrity": "sha512-FGW/iPWGyPFamAVZ60oCAthMqQrqafUGebF8UKuq/ha+e9SVG6YhJoRzurlQXOVf8dHfOhJ0ADMXyFnMc53clg==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.0.0-alpha.30", "@typescript-eslint/visitor-keys": "8.0.0-alpha.30" @@ -5650,9 +5032,8 @@ }, "node_modules/@tanstack/eslint-plugin-query/node_modules/@typescript-eslint/types": { "version": "8.0.0-alpha.30", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.0.0-alpha.30.tgz", - "integrity": "sha512-4WzLlw27SO9pK9UFj/Hu7WGo8WveT0SEiIpFVsV2WwtQmLps6kouwtVCB8GJPZKJyurhZhcqCoQVQFmpv441Vg==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -5663,9 +5044,8 @@ }, "node_modules/@tanstack/eslint-plugin-query/node_modules/@typescript-eslint/typescript-estree": { "version": "8.0.0-alpha.30", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.0.0-alpha.30.tgz", - "integrity": "sha512-WSXbc9ZcXI+7yC+6q95u77i8FXz6HOLsw3ST+vMUlFy1lFbXyFL/3e6HDKQCm2Clt0krnoCPiTGvIn+GkYPn4Q==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "8.0.0-alpha.30", "@typescript-eslint/visitor-keys": "8.0.0-alpha.30", @@ -5691,9 +5071,8 @@ }, "node_modules/@tanstack/eslint-plugin-query/node_modules/@typescript-eslint/utils": { "version": "8.0.0-alpha.30", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.0.0-alpha.30.tgz", - "integrity": "sha512-rfhqfLqFyXhHNDwMnHiVGxl/Z2q/3guQ1jLlGQ0hi9Rb7inmwz42crM+NnLPR+2vEnwyw1P/g7fnQgQ3qvFx4g==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.0.0-alpha.30", @@ -5713,9 +5092,8 @@ }, "node_modules/@tanstack/eslint-plugin-query/node_modules/@typescript-eslint/visitor-keys": { "version": "8.0.0-alpha.30", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.0.0-alpha.30.tgz", - "integrity": "sha512-XZuNurZxBqmr6ZIRIwWFq7j5RZd6ZlkId/HZEWyfciK+CWoyOxSF9Pv2VXH9Rlu2ZG2PfbhLz2Veszl4Pfn7yA==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.0.0-alpha.30", "eslint-visitor-keys": "^3.4.3" @@ -5730,9 +5108,8 @@ }, "node_modules/@tanstack/eslint-plugin-query/node_modules/semver": { "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -5742,8 +5119,7 @@ }, "node_modules/@tanstack/query-core": { "version": "5.51.1", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.51.1.tgz", - "integrity": "sha512-fJBMQMpo8/KSsWW5ratJR5+IFr7YNJ3K2kfP9l5XObYHsgfVy1w3FJUWU4FT2fj7+JMaEg33zOcNDBo0LMwHnw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" @@ -5751,8 +5127,7 @@ }, "node_modules/@tanstack/react-query": { "version": "5.51.1", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.51.1.tgz", - "integrity": "sha512-s47HKFnQ4HOJAHoIiXcpna/roMMPZJPy6fJ6p4ZNVn8+/onlLBEDd1+xc8OnDuwgvecqkZD7Z2mnSRbcWefrKw==", + "license": "MIT", "dependencies": { "@tanstack/query-core": "5.51.1" }, @@ -6116,30 +5491,26 @@ }, "node_modules/@types/cross-spawn": { "version": "6.0.6", - "resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.6.tgz", - "integrity": "sha512-fXRhhUkG4H3TQk5dBhQ7m/JDdSNHKwR2BBia62lhwEIq9xGiQKLxd6LymNhn47SjXhsUEPmxi+PKw2OkW4LLjA==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/doctrine": { "version": "0.0.9", - "resolved": "https://registry.npmjs.org/@types/doctrine/-/doctrine-0.0.9.tgz", - "integrity": "sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/emscripten": { "version": "1.39.13", - "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.39.13.tgz", - "integrity": "sha512-cFq+fO/isvhvmuP/+Sl4K4jtU6E23DoivtbO4r50e3odaxAiVdbfSYRDdJ4gCdxx+3aRjhphS5ZMwIH4hFy/Cw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/escodegen": { "version": "0.0.6", - "resolved": "https://registry.npmjs.org/@types/escodegen/-/escodegen-0.0.6.tgz", - "integrity": "sha512-AjwI4MvWx3HAOaZqYsjKWyEObT9lcVV0Y0V8nXo6cXzN8ZiMxVhf6F3d/UNvXVGKrEzL/Dluc5p+y9GkzlTWig==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/eslint": { "version": "8.56.10", @@ -6196,9 +5567,8 @@ }, "node_modules/@types/hast": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "*" } @@ -6273,15 +5643,13 @@ }, "node_modules/@types/lodash": { "version": "4.17.6", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.6.tgz", - "integrity": "sha512-OpXEVoCKSS3lQqjx9GGGOapBeuW5eUboYHRlHP9urXPX25IKZ6AnP5ZRxtVf63iieUbsHxLn8NQ5Nlftc6yzAA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/mdx": { "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", - "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/mime": { "version": "1.3.5", @@ -6350,9 +5718,8 @@ }, "node_modules/@types/resolve": { "version": "1.20.6", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.6.tgz", - "integrity": "sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/retry": { "version": "0.12.2", @@ -6361,9 +5728,8 @@ }, "node_modules/@types/semver": { "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/send": { "version": "0.17.4", @@ -6417,15 +5783,13 @@ }, "node_modules/@types/unist": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/uuid": { "version": "9.0.8", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", - "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/wrap-ansi": { "version": "3.0.0", @@ -6648,9 +6012,8 @@ }, "node_modules/@vitest/expect": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz", - "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==", "dev": true, + "license": "MIT", "dependencies": { "@vitest/spy": "1.6.0", "@vitest/utils": "1.6.0", @@ -6662,9 +6025,8 @@ }, "node_modules/@vitest/spy": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz", - "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==", "dev": true, + "license": "MIT", "dependencies": { "tinyspy": "^2.2.0" }, @@ -6674,9 +6036,8 @@ }, "node_modules/@vitest/utils": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz", - "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==", "dev": true, + "license": "MIT", "dependencies": { "diff-sequences": "^29.6.3", "estree-walker": "^3.0.3", @@ -6871,9 +6232,8 @@ }, "node_modules/@yarnpkg/fslib": { "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@yarnpkg/fslib/-/fslib-2.10.3.tgz", - "integrity": "sha512-41H+Ga78xT9sHvWLlFOZLIhtU6mTGZ20pZ29EiZa97vnxdohJD2AF42rCoAoWfqUz486xY6fhjMH+DYEM9r14A==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@yarnpkg/libzip": "^2.3.0", "tslib": "^1.13.0" @@ -6884,15 +6244,13 @@ }, "node_modules/@yarnpkg/fslib/node_modules/tslib": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/@yarnpkg/libzip": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/libzip/-/libzip-2.3.0.tgz", - "integrity": "sha512-6xm38yGVIa6mKm/DUCF2zFFJhERh/QWp1ufm4cNUvxsONBmfPg8uZ9pZBdOmF6qFGr/HlT6ABBkCSx/dlEtvWg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@types/emscripten": "^1.39.6", "tslib": "^1.13.0" @@ -6903,9 +6261,8 @@ }, "node_modules/@yarnpkg/libzip/node_modules/tslib": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/abab": { "version": "2.0.6", @@ -7274,18 +6631,16 @@ }, "node_modules/assertion-error": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true, + "license": "MIT", "engines": { "node": "*" } }, "node_modules/ast-types": { "version": "0.16.1", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", - "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.0.1" }, @@ -7300,9 +6655,8 @@ }, "node_modules/astral-regex": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -7344,9 +6698,8 @@ }, "node_modules/babel-core": { "version": "7.0.0-bridge.0", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", - "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==", "dev": true, + "license": "MIT", "peerDependencies": { "@babel/core": "^7.0.0-0" } @@ -7637,8 +6990,6 @@ }, "node_modules/base64-js": { "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true, "funding": [ { @@ -7653,7 +7004,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/batch": { "version": "0.6.1", @@ -7681,9 +7033,8 @@ }, "node_modules/bl": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "dev": true, + "license": "MIT", "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -7769,8 +7120,6 @@ }, "node_modules/browser-assert": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/browser-assert/-/browser-assert-1.2.1.tgz", - "integrity": "sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==", "dev": true }, "node_modules/browserslist": { @@ -7814,8 +7163,6 @@ }, "node_modules/buffer": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "dev": true, "funding": [ { @@ -7831,6 +7178,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -7926,18 +7274,16 @@ }, "node_modules/case-sensitive-paths-webpack-plugin": { "version": "2.4.0", - "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", - "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/chai": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", "dev": true, + "license": "MIT", "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.3", @@ -7990,9 +7336,8 @@ }, "node_modules/check-error": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, + "license": "MIT", "dependencies": { "get-func-name": "^2.0.2" }, @@ -8025,18 +7370,16 @@ }, "node_modules/chownr": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/chromatic": { "version": "11.5.5", - "resolved": "https://registry.npmjs.org/chromatic/-/chromatic-11.5.5.tgz", - "integrity": "sha512-YS0GJwegF0vpMbwZE68/xJlI4SlUGMqI78V2ATAF19YwTHaq8jGP1CPQGKUSlgWUhzPtyu3ELy6Dvv/owYljAg==", "dev": true, + "license": "MIT", "bin": { "chroma": "dist/bin.js", "chromatic": "dist/bin.js", @@ -8079,9 +7422,8 @@ }, "node_modules/citty": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz", - "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", "dev": true, + "license": "MIT", "dependencies": { "consola": "^3.2.3" } @@ -8275,9 +7617,8 @@ }, "node_modules/clone": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8" } @@ -8322,9 +7663,8 @@ }, "node_modules/colord": { "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/colorette": { "version": "2.0.20", @@ -8354,9 +7694,8 @@ }, "node_modules/commondir": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/compressible": { "version": "2.0.18", @@ -8411,9 +7750,8 @@ }, "node_modules/confbox": { "version": "0.1.7", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", - "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/connect-history-api-fallback": { "version": "2.0.0", @@ -8425,18 +7763,16 @@ }, "node_modules/consola": { "version": "3.2.3", - "resolved": "https://registry.npmjs.org/consola/-/consola-3.2.3.tgz", - "integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==", "dev": true, + "license": "MIT", "engines": { "node": "^14.18.0 || >=16.10.0" } }, "node_modules/constants-browserify": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/content-disposition": { "version": "0.5.4", @@ -8607,9 +7943,8 @@ }, "node_modules/crypto-random-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", - "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^1.0.1" }, @@ -8622,9 +7957,8 @@ }, "node_modules/crypto-random-string/node_modules/type-fest": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -8634,18 +7968,16 @@ }, "node_modules/css-functions-list": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.2.tgz", - "integrity": "sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12 || >=16" } }, "node_modules/css-loader": { "version": "6.11.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", - "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", "dev": true, + "license": "MIT", "dependencies": { "icss-utils": "^5.1.0", "postcss": "^8.4.33", @@ -8678,9 +8010,8 @@ }, "node_modules/css-loader/node_modules/semver": { "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -8705,9 +8036,8 @@ }, "node_modules/css-tree": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", "dev": true, + "license": "MIT", "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" @@ -8734,9 +8064,8 @@ }, "node_modules/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, + "license": "MIT", "bin": { "cssesc": "bin/cssesc" }, @@ -8870,9 +8199,8 @@ }, "node_modules/deep-eql": { "version": "4.1.4", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", - "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", "dev": true, + "license": "MIT", "dependencies": { "type-detect": "^4.0.0" }, @@ -8968,9 +8296,8 @@ }, "node_modules/defaults": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "dev": true, + "license": "MIT", "dependencies": { "clone": "^1.0.2" }, @@ -9023,9 +8350,8 @@ }, "node_modules/defu": { "version": "6.1.4", - "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", - "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/delayed-stream": { "version": "1.0.0", @@ -9062,9 +8388,8 @@ }, "node_modules/detect-indent": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -9217,9 +8542,8 @@ }, "node_modules/dotenv": { "version": "16.4.5", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", - "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=12" }, @@ -9276,9 +8600,8 @@ }, "node_modules/endent": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/endent/-/endent-2.1.0.tgz", - "integrity": "sha512-r8VyPX7XL8U01Xgnb1CjZ3XV+z90cXIJ9JPE/R9SEC9vpw2P6CfsRPJmp20DppC5N7ZAMCmjYkJIa744Iyg96w==", "dev": true, + "license": "MIT", "dependencies": { "dedent": "^0.7.0", "fast-json-parse": "^1.0.3", @@ -9287,9 +8610,8 @@ }, "node_modules/endent/node_modules/dedent": { "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/enhanced-resolve": { "version": "5.17.0", @@ -9316,9 +8638,8 @@ }, "node_modules/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, + "license": "MIT", "engines": { "node": ">=6" } @@ -9522,10 +8843,9 @@ }, "node_modules/esbuild": { "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -9560,9 +8880,8 @@ }, "node_modules/esbuild-register": { "version": "3.5.0", - "resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.5.0.tgz", - "integrity": "sha512-+4G/XmakeBAsvJuDugJvtyF1x+XJT4FMocynNpxrvEBViirpfUn2PgNpCHedfWhF4WokNsO/OvMKrmJOIJsI5A==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.3.4" }, @@ -9950,9 +9269,8 @@ }, "node_modules/eslint-plugin-storybook": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-0.8.0.tgz", - "integrity": "sha512-CZeVO5EzmPY7qghO2t64oaFM+8FTaD4uzOEjHKp516exyTKo+skKAL9GI3QALS2BXhyALJjNtwbmr1XinGE8bA==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/csf": "^0.0.1", "@typescript-eslint/utils": "^5.62.0", @@ -9968,18 +9286,16 @@ }, "node_modules/eslint-plugin-storybook/node_modules/@storybook/csf": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.0.1.tgz", - "integrity": "sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw==", "dev": true, + "license": "MIT", "dependencies": { "lodash": "^4.17.15" } }, "node_modules/eslint-plugin-storybook/node_modules/@typescript-eslint/scope-manager": { "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "5.62.0", "@typescript-eslint/visitor-keys": "5.62.0" @@ -9994,9 +9310,8 @@ }, "node_modules/eslint-plugin-storybook/node_modules/@typescript-eslint/types": { "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -10007,9 +9322,8 @@ }, "node_modules/eslint-plugin-storybook/node_modules/@typescript-eslint/typescript-estree": { "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "5.62.0", "@typescript-eslint/visitor-keys": "5.62.0", @@ -10034,9 +9348,8 @@ }, "node_modules/eslint-plugin-storybook/node_modules/@typescript-eslint/utils": { "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", @@ -10060,9 +9373,8 @@ }, "node_modules/eslint-plugin-storybook/node_modules/@typescript-eslint/visitor-keys": { "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "5.62.0", "eslint-visitor-keys": "^3.3.0" @@ -10077,9 +9389,8 @@ }, "node_modules/eslint-plugin-storybook/node_modules/semver": { "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -10389,9 +9700,8 @@ }, "node_modules/estree-walker": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0" } @@ -10545,9 +9855,8 @@ }, "node_modules/fast-json-parse": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fast-json-parse/-/fast-json-parse-1.0.3.tgz", - "integrity": "sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", @@ -10561,9 +9870,8 @@ }, "node_modules/fast-uri": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", - "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fastest-levenshtein": { "version": "1.0.16", @@ -10602,9 +9910,8 @@ }, "node_modules/fd-package-json": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fd-package-json/-/fd-package-json-1.2.0.tgz", - "integrity": "sha512-45LSPmWf+gC5tdCQMNH4s9Sr00bIkiD9aN7dc5hqkrEw1geRYyDQS1v1oMHAW3ysfxfndqGsrDREHHjNNbKUfA==", "dev": true, + "license": "MIT", "dependencies": { "walk-up-path": "^3.0.1" } @@ -10641,9 +9948,8 @@ }, "node_modules/filesize": { "version": "10.1.4", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.4.tgz", - "integrity": "sha512-ryBwPIIeErmxgPnm6cbESAzXjuEFubs+yKYLBZvg3CaiNcmkJChoOGcBSrZ6IwkMwPABwPpVXE6IlNdGJJrvEg==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">= 10.4.0" } @@ -10880,9 +10186,8 @@ }, "node_modules/flow-parser": { "version": "0.239.1", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.239.1.tgz", - "integrity": "sha512-topOrETNxJ6T2gAnQiWqAlzGPj8uI2wtmNOlDIMNB+qyvGJZ6R++STbUOTAYmvPhOMz2gXnXPH0hOvURYmrBow==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -11134,9 +10439,8 @@ }, "node_modules/fs-minipass": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "dev": true, + "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -11146,9 +10450,8 @@ }, "node_modules/fs-minipass/node_modules/minipass": { "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -11158,9 +10461,8 @@ }, "node_modules/fs-minipass/node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/fs-monkey": { "version": "1.0.6", @@ -11250,9 +10552,8 @@ }, "node_modules/get-func-name": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, + "license": "MIT", "engines": { "node": "*" } @@ -11312,9 +10613,8 @@ }, "node_modules/giget": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/giget/-/giget-1.2.3.tgz", - "integrity": "sha512-8EHPljDvs7qKykr6uw8b+lqLiUc/vUg+KVTI0uND4s63TdsZM2Xus3mflvF0DDG9SiM4RlCkFGL+7aAjRmV7KA==", "dev": true, + "license": "MIT", "dependencies": { "citty": "^0.1.6", "consola": "^3.2.3", @@ -11331,9 +10631,8 @@ }, "node_modules/github-slugger": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", - "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/glob": { "version": "10.4.5", @@ -11372,9 +10671,8 @@ }, "node_modules/global-modules": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", "dev": true, + "license": "MIT", "dependencies": { "global-prefix": "^3.0.0" }, @@ -11384,9 +10682,8 @@ }, "node_modules/global-prefix": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", "dev": true, + "license": "MIT", "dependencies": { "ini": "^1.3.5", "kind-of": "^6.0.2", @@ -11398,9 +10695,8 @@ }, "node_modules/global-prefix/node_modules/which": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -11459,9 +10755,8 @@ }, "node_modules/globjoin": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", - "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/gopd": { "version": "1.0.1", @@ -11572,9 +10867,8 @@ }, "node_modules/hast-util-heading-rank": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-3.0.0.tgz", - "integrity": "sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==", "dev": true, + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0" }, @@ -11585,9 +10879,8 @@ }, "node_modules/hast-util-is-element": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", - "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", "dev": true, + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0" }, @@ -11598,9 +10891,8 @@ }, "node_modules/hast-util-to-string": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.0.tgz", - "integrity": "sha512-OGkAxX1Ua3cbcW6EJ5pT/tslVb90uViVkcJ4ZZIMW/R33DX/AkcJcRrPebPwJkHYwlDHXz4aIwvAAaAdtrACFA==", "dev": true, + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0" }, @@ -11747,9 +11039,8 @@ }, "node_modules/html-tags": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", - "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -11971,9 +11262,8 @@ }, "node_modules/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, + "license": "ISC", "engines": { "node": "^10 || ^12 || >= 14" }, @@ -11983,8 +11273,6 @@ }, "node_modules/ieee754": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "dev": true, "funding": [ { @@ -11999,7 +11287,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/ignore": { "version": "5.3.1", @@ -12080,9 +11369,8 @@ }, "node_modules/ini": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/internal-slot": { "version": "1.0.7", @@ -12115,9 +11403,8 @@ }, "node_modules/is-absolute-url": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-4.0.1.tgz", - "integrity": "sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -12355,9 +11642,8 @@ }, "node_modules/is-interactive": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -12552,9 +11838,8 @@ }, "node_modules/is-unicode-supported": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -14378,9 +13663,8 @@ }, "node_modules/jscodeshift": { "version": "0.15.2", - "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.15.2.tgz", - "integrity": "sha512-FquR7Okgmc4Sd0aEDwqho3rEiKR3BdvuG9jfdHjLJ6JQoWSMpavug3AoIfnfWhxFlf+5pzQh8qjqz0DWFrNQzA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.23.0", "@babel/parser": "^7.23.0", @@ -14417,9 +13701,8 @@ }, "node_modules/jscodeshift/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, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -14432,9 +13715,8 @@ }, "node_modules/jscodeshift/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -14448,9 +13730,8 @@ }, "node_modules/jscodeshift/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, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -14460,15 +13741,13 @@ }, "node_modules/jscodeshift/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 + "dev": true, + "license": "MIT" }, "node_modules/jscodeshift/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, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -14478,9 +13757,8 @@ }, "node_modules/jscodeshift/node_modules/write-file-atomic": { "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "dev": true, + "license": "ISC", "dependencies": { "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", @@ -14622,9 +13900,8 @@ }, "node_modules/known-css-properties": { "version": "0.34.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.34.0.tgz", - "integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/language-subtag-registry": { "version": "0.3.23", @@ -15009,15 +14286,13 @@ }, "node_modules/lodash.truncate": { "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/log-symbols": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -15031,9 +14306,8 @@ }, "node_modules/log-symbols/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, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -15046,9 +14320,8 @@ }, "node_modules/log-symbols/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -15062,9 +14335,8 @@ }, "node_modules/log-symbols/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, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -15074,15 +14346,13 @@ }, "node_modules/log-symbols/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 + "dev": true, + "license": "MIT" }, "node_modules/log-symbols/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, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -15222,9 +14492,8 @@ }, "node_modules/loupe": { "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, + "license": "MIT", "dependencies": { "get-func-name": "^2.0.1" } @@ -15255,9 +14524,8 @@ }, "node_modules/magic-string": { "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } @@ -15292,15 +14560,13 @@ }, "node_modules/map-or-similar": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/map-or-similar/-/map-or-similar-1.5.0.tgz", - "integrity": "sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/markdown-to-jsx": { "version": "7.4.7", - "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.4.7.tgz", - "integrity": "sha512-0+ls1IQZdU6cwM1yu0ZjjiVWYtkbExSyUIFU2ZeDIFuZM1W42Mh4OlJ4nb4apX4H8smxDHRdFaoIVJGwfv5hkg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10" }, @@ -15310,9 +14576,8 @@ }, "node_modules/mathml-tag-names": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", - "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -15320,9 +14585,8 @@ }, "node_modules/mdn-data": { "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "dev": true + "dev": true, + "license": "CC0-1.0" }, "node_modules/media-typer": { "version": "0.3.0", @@ -15352,18 +14616,16 @@ }, "node_modules/memoizerific": { "version": "1.11.3", - "resolved": "https://registry.npmjs.org/memoizerific/-/memoizerific-1.11.3.tgz", - "integrity": "sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==", "dev": true, + "license": "MIT", "dependencies": { "map-or-similar": "^1.5.0" } }, "node_modules/meow": { "version": "13.2.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", - "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -15492,9 +14754,8 @@ }, "node_modules/minizlib": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "dev": true, + "license": "MIT", "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" @@ -15505,9 +14766,8 @@ }, "node_modules/minizlib/node_modules/minipass": { "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -15517,15 +14777,13 @@ }, "node_modules/minizlib/node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/mkdirp": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, + "license": "MIT", "bin": { "mkdirp": "bin/cmd.js" }, @@ -15535,9 +14793,8 @@ }, "node_modules/mlly": { "version": "1.7.1", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.1.tgz", - "integrity": "sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==", "dev": true, + "license": "MIT", "dependencies": { "acorn": "^8.11.3", "pathe": "^1.1.2", @@ -15685,8 +14942,6 @@ }, "node_modules/nanoid": { "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true, "funding": [ { @@ -15694,6 +14949,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -15735,9 +14991,8 @@ }, "node_modules/node-dir": { "version": "0.1.17", - "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", - "integrity": "sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==", "dev": true, + "license": "MIT", "dependencies": { "minimatch": "^3.0.2" }, @@ -15747,9 +15002,8 @@ }, "node_modules/node-dir/node_modules/brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -15757,9 +15011,8 @@ }, "node_modules/node-dir/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -15769,9 +15022,8 @@ }, "node_modules/node-fetch-native": { "version": "1.6.4", - "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.4.tgz", - "integrity": "sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-forge": { "version": "1.3.1", @@ -15828,9 +15080,8 @@ }, "node_modules/nypm": { "version": "0.3.9", - "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.3.9.tgz", - "integrity": "sha512-BI2SdqqTHg2d4wJh8P9A1W+bslg33vOE9IZDY6eR2QC+Pu1iNBVZUqczrd43rJb+fMzHU7ltAYKsEFY/kHMFcw==", "dev": true, + "license": "MIT", "dependencies": { "citty": "^0.1.6", "consola": "^3.2.3", @@ -15848,9 +15099,8 @@ }, "node_modules/nypm/node_modules/execa": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", @@ -15871,9 +15121,8 @@ }, "node_modules/nypm/node_modules/get-stream": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, + "license": "MIT", "engines": { "node": ">=16" }, @@ -15883,18 +15132,16 @@ }, "node_modules/nypm/node_modules/human-signals": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=16.17.0" } }, "node_modules/nypm/node_modules/is-stream": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -15904,9 +15151,8 @@ }, "node_modules/nypm/node_modules/mimic-fn": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -15916,9 +15162,8 @@ }, "node_modules/nypm/node_modules/npm-run-path": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^4.0.0" }, @@ -15931,9 +15176,8 @@ }, "node_modules/nypm/node_modules/onetime": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^4.0.0" }, @@ -15946,9 +15190,8 @@ }, "node_modules/nypm/node_modules/path-key": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -15958,9 +15201,8 @@ }, "node_modules/nypm/node_modules/signal-exit": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, + "license": "ISC", "engines": { "node": ">=14" }, @@ -15970,9 +15212,8 @@ }, "node_modules/nypm/node_modules/strip-final-newline": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -16116,9 +15357,8 @@ }, "node_modules/objectorarray": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/objectorarray/-/objectorarray-1.0.5.tgz", - "integrity": "sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/obuf": { "version": "1.1.2", @@ -16127,9 +15367,8 @@ }, "node_modules/ohash": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.3.tgz", - "integrity": "sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/on-finished": { "version": "2.4.1", @@ -16207,9 +15446,8 @@ }, "node_modules/ora": { "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", "dev": true, + "license": "MIT", "dependencies": { "bl": "^4.1.0", "chalk": "^4.1.0", @@ -16230,9 +15468,8 @@ }, "node_modules/ora/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, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -16245,9 +15482,8 @@ }, "node_modules/ora/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -16261,9 +15497,8 @@ }, "node_modules/ora/node_modules/cli-cursor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, + "license": "MIT", "dependencies": { "restore-cursor": "^3.1.0" }, @@ -16273,9 +15508,8 @@ }, "node_modules/ora/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, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -16285,15 +15519,13 @@ }, "node_modules/ora/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 + "dev": true, + "license": "MIT" }, "node_modules/ora/node_modules/restore-cursor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, + "license": "MIT", "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -16304,9 +15536,8 @@ }, "node_modules/ora/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, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -16438,9 +15669,8 @@ }, "node_modules/path-browserify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-exists": { "version": "4.0.0", @@ -16504,15 +15734,13 @@ }, "node_modules/pathe": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/pathval": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true, + "license": "MIT", "engines": { "node": "*" } @@ -16572,9 +15800,8 @@ }, "node_modules/pkg-types": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.3.tgz", - "integrity": "sha512-+JrgthZG6m3ckicaOB74TwQ+tBWsFl3qVQg7mN8ulwSOElJ7gBhKzj2VkCPnZ4NlF6kEquYU+RIYNVAvzd54UA==", "dev": true, + "license": "MIT", "dependencies": { "confbox": "^0.1.7", "mlly": "^1.7.1", @@ -16583,9 +15810,8 @@ }, "node_modules/polished": { "version": "4.3.1", - "resolved": "https://registry.npmjs.org/polished/-/polished-4.3.1.tgz", - "integrity": "sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/runtime": "^7.17.8" }, @@ -16603,8 +15829,6 @@ }, "node_modules/postcss": { "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", "dev": true, "funding": [ { @@ -16620,6 +15844,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.1", @@ -16631,9 +15856,8 @@ }, "node_modules/postcss-modules-extract-imports": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", - "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", "dev": true, + "license": "ISC", "engines": { "node": "^10 || ^12 || >= 14" }, @@ -16643,9 +15867,8 @@ }, "node_modules/postcss-modules-local-by-default": { "version": "4.0.5", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", - "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", "dev": true, + "license": "MIT", "dependencies": { "icss-utils": "^5.0.0", "postcss-selector-parser": "^6.0.2", @@ -16660,9 +15883,8 @@ }, "node_modules/postcss-modules-scope": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", - "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", "dev": true, + "license": "ISC", "dependencies": { "postcss-selector-parser": "^6.0.4" }, @@ -16675,9 +15897,8 @@ }, "node_modules/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, + "license": "ISC", "dependencies": { "icss-utils": "^5.0.0" }, @@ -16690,14 +15911,11 @@ }, "node_modules/postcss-resolve-nested-selector": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", - "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/postcss-safe-parser": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.0.tgz", - "integrity": "sha512-ovehqRNVCpuFzbXoTb4qLtyzK3xn3t/CUBxOs8LsnQjQrShaB4lKiHoVqY8ANaC0hBMHq5QVWk77rwGklFUDrg==", "dev": true, "funding": [ { @@ -16713,6 +15931,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "engines": { "node": ">=18.0" }, @@ -16722,9 +15941,8 @@ }, "node_modules/postcss-selector-parser": { "version": "6.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", - "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==", "dev": true, + "license": "MIT", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -16735,18 +15953,16 @@ }, "node_modules/postcss-sorting": { "version": "8.0.2", - "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-8.0.2.tgz", - "integrity": "sha512-M9dkSrmU00t/jK7rF6BZSZauA5MAaBW4i5EnJXspMwt4iqTh/L9j6fgMnbElEOfyRyfLfVbIHj/R52zHzAPe1Q==", "dev": true, + "license": "MIT", "peerDependencies": { "postcss": "^8.4.20" } }, "node_modules/postcss-styled-syntax": { "version": "0.6.4", - "resolved": "https://registry.npmjs.org/postcss-styled-syntax/-/postcss-styled-syntax-0.6.4.tgz", - "integrity": "sha512-uWiLn+9rKgIghUYmTHvXMR6MnyPULMe9Gv3bV537Fg4FH6CA6cn21WMjKss2Qb98LUhT847tKfnRGG3FhSOgUQ==", "dev": true, + "license": "MIT", "dependencies": { "typescript": "^5.3.3" }, @@ -16759,9 +15975,8 @@ }, "node_modules/postcss-value-parser": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/prelude-ls": { "version": "1.2.1", @@ -16825,9 +16040,8 @@ }, "node_modules/process": { "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6.0" } @@ -16995,9 +16209,8 @@ }, "node_modules/react-colorful": { "version": "5.6.1", - "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-5.6.1.tgz", - "integrity": "sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==", "dev": true, + "license": "MIT", "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" @@ -17005,9 +16218,8 @@ }, "node_modules/react-confetti": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/react-confetti/-/react-confetti-6.1.0.tgz", - "integrity": "sha512-7Ypx4vz0+g8ECVxr88W9zhcQpbeujJAVqL14ZnXJ3I23mOI9/oBVTQ3dkJhUmB0D6XOtCZEM6N0Gm9PMngkORw==", "dev": true, + "license": "MIT", "dependencies": { "tween-functions": "^1.2.0" }, @@ -17020,9 +16232,8 @@ }, "node_modules/react-docgen": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-7.0.3.tgz", - "integrity": "sha512-i8aF1nyKInZnANZ4uZrH49qn1paRgBZ7wZiCNBMnenlPzEv0mRl+ShpTVEI6wZNl8sSc79xZkivtgLKQArcanQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.18.9", "@babel/traverse": "^7.18.9", @@ -17041,18 +16252,16 @@ }, "node_modules/react-docgen-typescript": { "version": "2.2.2", - "resolved": "https://registry.npmjs.org/react-docgen-typescript/-/react-docgen-typescript-2.2.2.tgz", - "integrity": "sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg==", "dev": true, + "license": "MIT", "peerDependencies": { "typescript": ">= 4.3.x" } }, "node_modules/react-docgen/node_modules/strip-indent": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", - "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", "dev": true, + "license": "MIT", "dependencies": { "min-indent": "^1.0.1" }, @@ -17076,9 +16285,8 @@ }, "node_modules/react-element-to-jsx-string": { "version": "15.0.0", - "resolved": "https://registry.npmjs.org/react-element-to-jsx-string/-/react-element-to-jsx-string-15.0.0.tgz", - "integrity": "sha512-UDg4lXB6BzlobN60P8fHWVPX3Kyw8ORrTeBtClmIlGdkOOE+GYQSFvmEU5iLLpwp/6v42DINwNcwOhOLfQ//FQ==", "dev": true, + "license": "MIT", "dependencies": { "@base2/pretty-print-object": "1.0.1", "is-plain-object": "5.0.0", @@ -17091,18 +16299,16 @@ }, "node_modules/react-element-to-jsx-string/node_modules/is-plain-object": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/react-element-to-jsx-string/node_modules/react-is": { "version": "18.1.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz", - "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/react-is": { "version": "16.13.1", @@ -17110,8 +16316,7 @@ }, "node_modules/react-router": { "version": "6.24.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.24.1.tgz", - "integrity": "sha512-PTXFXGK2pyXpHzVo3rR9H7ip4lSPZZc0bHG5CARmj65fTT6qG7sTngmb6lcYu1gf3y/8KxORoy9yn59pGpCnpg==", + "license": "MIT", "dependencies": { "@remix-run/router": "1.17.1" }, @@ -17124,8 +16329,7 @@ }, "node_modules/react-router-dom": { "version": "6.24.1", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.24.1.tgz", - "integrity": "sha512-U19KtXqooqw967Vw0Qcn5cOvrX5Ejo9ORmOtJMzYWtCT4/WOfFLIZGGsVLxcd9UkBO0mSTZtXqhZBsWlHr7+Sg==", + "license": "MIT", "dependencies": { "@remix-run/router": "1.17.1", "react-router": "6.24.1" @@ -17164,9 +16368,8 @@ }, "node_modules/recast": { "version": "0.23.9", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.9.tgz", - "integrity": "sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==", "dev": true, + "license": "MIT", "dependencies": { "ast-types": "^0.16.1", "esprima": "~4.0.0", @@ -17302,9 +16505,8 @@ }, "node_modules/rehype-external-links": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/rehype-external-links/-/rehype-external-links-3.0.0.tgz", - "integrity": "sha512-yp+e5N9V3C6bwBeAC4n796kc86M4gJCdlVhiMTxIrJG5UHDMh+PJANf9heqORJbt1nrCbDwIlAZKjANIaVBbvw==", "dev": true, + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "@ungap/structured-clone": "^1.0.0", @@ -17320,9 +16522,8 @@ }, "node_modules/rehype-slug": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/rehype-slug/-/rehype-slug-6.0.0.tgz", - "integrity": "sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==", "dev": true, + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "github-slugger": "^2.0.0", @@ -17373,9 +16574,8 @@ }, "node_modules/requireindex": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", - "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.5" } @@ -17934,9 +17134,8 @@ }, "node_modules/source-map-js": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -17952,9 +17151,8 @@ }, "node_modules/space-separated-tokens": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -18033,9 +17231,8 @@ }, "node_modules/storybook": { "version": "8.2.3", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.2.3.tgz", - "integrity": "sha512-uGjoFasTDWaeLp+pz8jCdKfSOvBTNEBpGf2C+pwZkJpd5CHrUlq4dkfE0/Kv/MtyQI1W9Fgbinbj7ggNe0D3Cg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.24.4", "@babel/types": "^7.24.0", @@ -18078,9 +17275,8 @@ }, "node_modules/storybook/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, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -18093,9 +17289,8 @@ }, "node_modules/storybook/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -18109,9 +17304,8 @@ }, "node_modules/storybook/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, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -18121,24 +17315,21 @@ }, "node_modules/storybook/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 + "dev": true, + "license": "MIT" }, "node_modules/storybook/node_modules/commander": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/storybook/node_modules/find-up": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -18152,9 +17343,8 @@ }, "node_modules/storybook/node_modules/fs-extra": { "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -18166,9 +17356,8 @@ }, "node_modules/storybook/node_modules/globby": { "version": "14.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", - "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", "dev": true, + "license": "MIT", "dependencies": { "@sindresorhus/merge-streams": "^2.1.0", "fast-glob": "^3.3.2", @@ -18186,9 +17375,8 @@ }, "node_modules/storybook/node_modules/locate-path": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -18201,9 +17389,8 @@ }, "node_modules/storybook/node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -18216,9 +17403,8 @@ }, "node_modules/storybook/node_modules/p-locate": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -18231,9 +17417,8 @@ }, "node_modules/storybook/node_modules/path-type": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", - "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -18243,9 +17428,8 @@ }, "node_modules/storybook/node_modules/semver": { "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -18255,9 +17439,8 @@ }, "node_modules/storybook/node_modules/slash": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.16" }, @@ -18267,9 +17450,8 @@ }, "node_modules/storybook/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, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -18279,9 +17461,8 @@ }, "node_modules/storybook/node_modules/yocto-queue": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -18525,9 +17706,8 @@ }, "node_modules/style-loader": { "version": "3.3.4", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", - "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 12.13.0" }, @@ -18541,8 +17721,6 @@ }, "node_modules/stylelint": { "version": "16.7.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.7.0.tgz", - "integrity": "sha512-Q1ATiXlz+wYr37a7TGsfvqYn2nSR3T/isw3IWlZQzFzCNoACHuGBb6xBplZXz56/uDRJHIygxjh7jbV/8isewA==", "dev": true, "funding": [ { @@ -18554,6 +17732,7 @@ "url": "https://github.com/sponsors/stylelint" } ], + "license": "MIT", "dependencies": { "@csstools/css-parser-algorithms": "^2.7.1", "@csstools/css-tokenizer": "^2.4.1", @@ -18604,8 +17783,6 @@ }, "node_modules/stylelint-config-recommended": { "version": "14.0.1", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-14.0.1.tgz", - "integrity": "sha512-bLvc1WOz/14aPImu/cufKAZYfXs/A/owZfSMZ4N+16WGXLoX5lOir53M6odBxvhgmgdxCVnNySJmZKx73T93cg==", "dev": true, "funding": [ { @@ -18617,6 +17794,7 @@ "url": "https://github.com/sponsors/stylelint" } ], + "license": "MIT", "engines": { "node": ">=18.12.0" }, @@ -18626,8 +17804,6 @@ }, "node_modules/stylelint-config-standard": { "version": "36.0.1", - "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-36.0.1.tgz", - "integrity": "sha512-8aX8mTzJ6cuO8mmD5yon61CWuIM4UD8Q5aBcWKGSf6kg+EC3uhB+iOywpTK4ca6ZL7B49en8yanOFtUW0qNzyw==", "dev": true, "funding": [ { @@ -18639,6 +17815,7 @@ "url": "https://github.com/sponsors/stylelint" } ], + "license": "MIT", "dependencies": { "stylelint-config-recommended": "^14.0.1" }, @@ -18651,9 +17828,8 @@ }, "node_modules/stylelint-order": { "version": "6.0.4", - "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-6.0.4.tgz", - "integrity": "sha512-0UuKo4+s1hgQ/uAxlYU4h0o0HS4NiQDud0NAUNI0aa8FJdmYHA5ZZTFHiV5FpmE3071e9pZx5j0QpVJW5zOCUA==", "dev": true, + "license": "MIT", "dependencies": { "postcss": "^8.4.32", "postcss-sorting": "^8.0.2" @@ -18664,15 +17840,13 @@ }, "node_modules/stylelint/node_modules/balanced-match": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", - "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/stylelint/node_modules/cosmiconfig": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", - "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, + "license": "MIT", "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", @@ -18696,15 +17870,13 @@ }, "node_modules/stylelint/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/stylelint/node_modules/file-entry-cache": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.0.0.tgz", - "integrity": "sha512-6MgEugi8p2tiUhqO7GnPsmbCCzj0YRCwwaTbpGRyKZesjRSzkqkAE9fPp7V2yMs5hwfgbQLgdvSSkGNg1s5Uvw==", "dev": true, + "license": "MIT", "dependencies": { "flat-cache": "^5.0.0" }, @@ -18714,9 +17886,8 @@ }, "node_modules/stylelint/node_modules/flat-cache": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-5.0.0.tgz", - "integrity": "sha512-JrqFmyUl2PnPi1OvLyTVHnQvwQ0S+e6lGSwu8OkAZlSaNIZciTY2H/cOOROxsBA1m/LZNHDsqAgDZt6akWcjsQ==", "dev": true, + "license": "MIT", "dependencies": { "flatted": "^3.3.1", "keyv": "^4.5.4" @@ -18727,18 +17898,16 @@ }, "node_modules/stylelint/node_modules/is-plain-object": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/stylelint/node_modules/signal-exit": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, + "license": "ISC", "engines": { "node": ">=14" }, @@ -18748,9 +17917,8 @@ }, "node_modules/stylelint/node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -18762,9 +17930,8 @@ }, "node_modules/stylelint/node_modules/string-width/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -18774,9 +17941,8 @@ }, "node_modules/stylelint/node_modules/strip-ansi": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -18789,9 +17955,8 @@ }, "node_modules/stylelint/node_modules/strip-ansi/node_modules/ansi-regex": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -18801,9 +17966,8 @@ }, "node_modules/stylelint/node_modules/write-file-atomic": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", "dev": true, + "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" @@ -18832,9 +17996,8 @@ }, "node_modules/supports-hyperlinks": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", - "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" @@ -18845,9 +18008,8 @@ }, "node_modules/supports-hyperlinks/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, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -18867,15 +18029,12 @@ }, "node_modules/svg-tags": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", - "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", "dev": true }, "node_modules/swc-loader": { "version": "0.2.6", - "resolved": "https://registry.npmjs.org/swc-loader/-/swc-loader-0.2.6.tgz", - "integrity": "sha512-9Zi9UP2YmDpgmQVbyOPJClY0dwf58JDyDMQ7uRc4krmc72twNI2fvlBWHLqVekBpPc7h5NJkGVT1zNDxFrqhvg==", "dev": true, + "license": "MIT", "dependencies": { "@swc/counter": "^0.1.3" }, @@ -18891,9 +18050,8 @@ }, "node_modules/table": { "version": "6.8.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", - "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", @@ -18907,9 +18065,8 @@ }, "node_modules/table/node_modules/ajv": { "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -18923,9 +18080,8 @@ }, "node_modules/table/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, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -18938,9 +18094,8 @@ }, "node_modules/table/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, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -18950,27 +18105,23 @@ }, "node_modules/table/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 + "dev": true, + "license": "MIT" }, "node_modules/table/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/table/node_modules/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==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/table/node_modules/slice-ansi": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -18985,9 +18136,8 @@ }, "node_modules/table/node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -19007,9 +18157,8 @@ }, "node_modules/tar": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", "dev": true, + "license": "ISC", "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", @@ -19024,33 +18173,29 @@ }, "node_modules/tar/node_modules/minipass": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", "dev": true, + "license": "ISC", "engines": { "node": ">=8" } }, "node_modules/tar/node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/telejson": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/telejson/-/telejson-7.2.0.tgz", - "integrity": "sha512-1QTEcJkJEhc8OnStBx/ILRu5J2p0GjvWsBx56bmZRqnrkdBMUe+nX92jxV+p3dB4CP6PZCdJMQJwCggkNBMzkQ==", "dev": true, + "license": "MIT", "dependencies": { "memoizerific": "^1.11.3" } }, "node_modules/temp": { "version": "0.8.4", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.4.tgz", - "integrity": "sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==", "dev": true, + "license": "MIT", "dependencies": { "rimraf": "~2.6.2" }, @@ -19060,18 +18205,16 @@ }, "node_modules/temp-dir": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", - "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.16" } }, "node_modules/temp/node_modules/brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -19079,10 +18222,8 @@ }, "node_modules/temp/node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -19100,9 +18241,8 @@ }, "node_modules/temp/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -19112,10 +18252,8 @@ }, "node_modules/temp/node_modules/rimraf": { "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -19125,9 +18263,8 @@ }, "node_modules/tempy": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-3.1.0.tgz", - "integrity": "sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==", "dev": true, + "license": "MIT", "dependencies": { "is-stream": "^3.0.0", "temp-dir": "^3.0.0", @@ -19143,9 +18280,8 @@ }, "node_modules/tempy/node_modules/is-stream": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -19155,9 +18291,8 @@ }, "node_modules/tempy/node_modules/type-fest": { "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=12.20" }, @@ -19290,15 +18425,13 @@ }, "node_modules/tiny-invariant": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", - "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/tinyspy": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", - "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.0.0" } @@ -19395,9 +18528,8 @@ }, "node_modules/ts-dedent": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", - "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.10" } @@ -19525,9 +18657,8 @@ }, "node_modules/tsutils": { "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^1.8.1" }, @@ -19540,15 +18671,13 @@ }, "node_modules/tsutils/node_modules/tslib": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/tween-functions": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tween-functions/-/tween-functions-1.2.0.tgz", - "integrity": "sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA==", - "dev": true + "dev": true, + "license": "BSD" }, "node_modules/type-check": { "version": "0.4.0", @@ -19675,9 +18804,8 @@ }, "node_modules/ufo": { "version": "1.5.3", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", - "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/unbox-primitive": { "version": "1.0.2", @@ -19693,6 +18821,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici": { + "version": "5.28.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", + "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", + "dev": true, + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, "node_modules/undici-types": { "version": "5.26.5", "dev": true, @@ -19736,9 +18876,8 @@ }, "node_modules/unicorn-magic": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", - "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -19748,9 +18887,8 @@ }, "node_modules/unique-string": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", - "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", "dev": true, + "license": "MIT", "dependencies": { "crypto-random-string": "^4.0.0" }, @@ -19763,9 +18901,8 @@ }, "node_modules/unist-util-is": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" }, @@ -19776,9 +18913,8 @@ }, "node_modules/unist-util-visit": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", @@ -19791,9 +18927,8 @@ }, "node_modules/unist-util-visit-parents": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" @@ -19821,9 +18956,8 @@ }, "node_modules/unplugin": { "version": "1.11.0", - "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.11.0.tgz", - "integrity": "sha512-3r7VWZ/webh0SGgJScpWl2/MRCZK5d3ZYFcNaeci/GQ7Teop7zf0Nl2pUuz7G21BwPd9pcUPOC5KmJ2L3WgC5g==", "dev": true, + "license": "MIT", "dependencies": { "acorn": "^8.11.3", "chokidar": "^3.6.0", @@ -19873,9 +19007,8 @@ }, "node_modules/url": { "version": "0.11.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", - "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", "dev": true, + "license": "MIT", "dependencies": { "punycode": "^1.4.1", "qs": "^6.11.2" @@ -19892,15 +19025,13 @@ }, "node_modules/url/node_modules/punycode": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/url/node_modules/qs": { "version": "6.12.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.3.tgz", - "integrity": "sha512-AWJm14H1vVaO/iNZ4/hO+HyaTehuy9nRqVdkTqlJt0HWvBiBIEXFmb4C0DGeYo3Xes9rrEW+TxHsaigCbN5ICQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.6" }, @@ -19913,9 +19044,8 @@ }, "node_modules/util": { "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", @@ -19984,9 +19114,8 @@ }, "node_modules/walk-up-path": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-3.0.1.tgz", - "integrity": "sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/walker": { "version": "1.0.8", @@ -20018,9 +19147,8 @@ }, "node_modules/wcwidth": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "dev": true, + "license": "MIT", "dependencies": { "defaults": "^1.0.3" } @@ -20330,9 +19458,8 @@ }, "node_modules/webpack-hot-middleware": { "version": "2.26.1", - "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.26.1.tgz", - "integrity": "sha512-khZGfAeJx6I8K9zKohEWWYN6KDlVw2DHownoe+6Vtwj1LP9WFgegXnVMSkZ/dBEBtXFwrkkydsaPFlB7f8wU2A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-html-community": "0.0.8", "html-entities": "^2.1.0", @@ -20362,9 +19489,8 @@ }, "node_modules/webpack-virtual-modules": { "version": "0.6.2", - "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", - "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/websocket-driver": { "version": "0.7.4", diff --git a/frontend/package.json b/frontend/package.json index 81d82dc2..25922ed2 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -77,6 +77,7 @@ "stylelint-order": "^6.0.4", "ts-loader": "^9.5.1", "typescript": "^5.5.3", + "undici": "^5.28.4", "webpack": "^5.92.1", "webpack-cli": "^5.1.4", "webpack-dev-server": "^5.0.4", From 3931972b790b975c1d9f2df3dd90f65ef82bf0a1 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 18 Jul 2024 00:24:07 +0900 Subject: [PATCH 0089/1013] =?UTF-8?q?fix:=20msw/node=20=EA=B0=80=20node=20?= =?UTF-8?q?18=20=EC=9D=B4=EC=83=81=EC=97=90=EC=84=9C=20=EB=8F=99=EC=9E=91?= =?UTF-8?q?=ED=95=98=EA=B8=B0=20=EC=9C=84=ED=95=9C=20polyfill=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20#25?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.eslintrc.json | 7 ++++++- frontend/jest.config.json | 4 ++++ frontend/jest.polyfills.js | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 frontend/jest.polyfills.js diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json index 9fbeff47..ec2f4829 100644 --- a/frontend/.eslintrc.json +++ b/frontend/.eslintrc.json @@ -20,7 +20,12 @@ "sourceType": "module" }, "plugins": ["react", "@typescript-eslint", "react-refresh"], - "ignorePatterns": ["webpack.config.common.js", "webpack.config.dev.js", "webpack.config.prod.js"], + "ignorePatterns": [ + "webpack.config.common.js", + "webpack.config.dev.js", + "webpack.config.prod.js", + "jest.polyfills.js" + ], "rules": { "react/react-in-jsx-scope": "off", "@typescript-eslint/no-unused-vars": "warn", diff --git a/frontend/jest.config.json b/frontend/jest.config.json index 831d9051..d06f8783 100644 --- a/frontend/jest.config.json +++ b/frontend/jest.config.json @@ -1,7 +1,11 @@ { "testEnvironment": "jsdom", + "testEnvironmentOptions": { + "customExportConditions": [""] + }, "moduleNameMapper": { "^@/(.*)$": "/src/$1" }, + "setupFiles": ["./jest.polyfills.js"], "setupFilesAfterEnv": ["/jest.setup.ts"] } diff --git a/frontend/jest.polyfills.js b/frontend/jest.polyfills.js new file mode 100644 index 00000000..805e8375 --- /dev/null +++ b/frontend/jest.polyfills.js @@ -0,0 +1,32 @@ +// jest.polyfills.js +/** + * @note The block below contains polyfills for Node.js globals + * required for Jest to function when running JSDOM tests. + * These HAVE to be require's and HAVE to be in this exact + * order, since "undici" depends on the "TextEncoder" global API. + * + * Consider migrating to a more modern test runner if + * you don't want to deal with this. + */ + +const { TextDecoder, TextEncoder } = require('node:util'); + +Object.defineProperties(globalThis, { + TextDecoder: { value: TextDecoder }, + TextEncoder: { value: TextEncoder }, +}); + +const { Blob, File } = require('node:buffer'); + +const { fetch, Headers, FormData, Request, Response, ReadableStream } = require('undici'); + +Object.defineProperties(globalThis, { + fetch: { value: fetch, writable: true }, + Blob: { value: Blob }, + File: { value: File }, + Headers: { value: Headers }, + FormData: { value: FormData }, + Request: { value: Request }, + Response: { value: Response }, + ReadableStream: { value: ReadableStream }, +}); From 0668c4cbd7922b7817055b18b84752d6fc6aef1e Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 18 Jul 2024 00:31:23 +0900 Subject: [PATCH 0090/1013] =?UTF-8?q?feat:=20msw=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=ED=99=98=EA=B2=BD=20=EC=88=98=EC=A0=95=20=EB=B0=8F?= =?UTF-8?q?=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?mock=20wrapper=20=EA=B5=AC=ED=98=84=20#25?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/jest.setup.ts | 5 +++++ frontend/src/mocks/server.ts | 12 ------------ frontend/src/mocks/wrapper.tsx | 27 +++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 12 deletions(-) create mode 100644 frontend/src/mocks/wrapper.tsx diff --git a/frontend/jest.setup.ts b/frontend/jest.setup.ts index 7b0828bf..47e5cdb0 100644 --- a/frontend/jest.setup.ts +++ b/frontend/jest.setup.ts @@ -1 +1,6 @@ import '@testing-library/jest-dom'; +import { server } from './src/mocks/server'; + +beforeAll(() => server.listen()); +afterEach(() => server.resetHandlers()); +afterAll(() => server.close()); diff --git a/frontend/src/mocks/server.ts b/frontend/src/mocks/server.ts index 8a51966b..5ac9204f 100644 --- a/frontend/src/mocks/server.ts +++ b/frontend/src/mocks/server.ts @@ -3,15 +3,3 @@ import { setupServer } from 'msw/node'; import { handlers } from './handlers'; export const server = setupServer(...handlers); - -beforeAll(() => { - server.listen({ onUnhandledRequest: 'error' }); -}); - -afterEach(() => { - server.resetHandlers(); -}); - -afterAll(() => { - server.close(); -}); diff --git a/frontend/src/mocks/wrapper.tsx b/frontend/src/mocks/wrapper.tsx new file mode 100644 index 00000000..1a9ac015 --- /dev/null +++ b/frontend/src/mocks/wrapper.tsx @@ -0,0 +1,27 @@ +import { Global, ThemeProvider } from '@emotion/react'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { PropsWithChildren } from 'react'; + +import GlobalStyle from '@/styles/GlobalStyle'; +import { Theme } from '@/styles/Theme'; + +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + }, + }, +}); + +const wrapper = ({ children }: PropsWithChildren) => { + return ( + + + + {children} + + + ); +}; + +export default wrapper; From 9b734b5f34683d4ccadbdb46b877d2ac05d57a83 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Fri, 19 Jul 2024 20:50:41 +0900 Subject: [PATCH 0091/1013] =?UTF-8?q?fix:=20babel=EB=A1=9C=20build=20?= =?UTF-8?q?=EC=8B=9C=20emotion=20css=20prop=20=EC=98=A4=EB=A5=98=EB=82=98?= =?UTF-8?q?=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0=20#25?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.babelrc | 3 +- frontend/package-lock.json | 593 +++++++++++++++++++++++++++----- frontend/package.json | 1 + frontend/tsconfig.json | 1 + frontend/webpack.config.prod.js | 4 + 5 files changed, 516 insertions(+), 86 deletions(-) diff --git a/frontend/.babelrc b/frontend/.babelrc index ed266ad8..17323b59 100644 --- a/frontend/.babelrc +++ b/frontend/.babelrc @@ -9,7 +9,8 @@ "shippedProposals": true } ], + "@emotion/babel-preset-css-prop", "@babel/preset-typescript", - ["@babel/preset-react", { "runtime": "automatic" }] + ["@babel/preset-react", { "runtime": "automatic", "importSource": "@emotion/react" }] ] } diff --git a/frontend/package-lock.json b/frontend/package-lock.json index c502529e..b3ad8d0b 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -22,6 +22,7 @@ "@babel/preset-react": "^7.24.7", "@babel/preset-typescript": "^7.24.7", "@chromatic-com/storybook": "^1.6.1", + "@emotion/babel-preset-css-prop": "^11.11.0", "@storybook/addon-essentials": "^8.2.2", "@storybook/addon-interactions": "^8.2.2", "@storybook/addon-links": "^8.2.2", @@ -73,9 +74,6 @@ "webpack-cli": "^5.1.4", "webpack-dev-server": "^5.0.4", "webpack-merge": "^6.0.1" - }, - "engines": { - "node": "18.x" } }, "node_modules/@adobe/css-tools": { @@ -692,8 +690,9 @@ }, "node_modules/@babel/plugin-syntax-flow": { "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.24.7.tgz", + "integrity": "sha512-9G8GYT/dxn/D1IIKOUBmGX0mnmj46mGH9NnZyJLwtCpgh5f7D2VbuKodb+2s9m1Yavh1s7ASQN8lf0eqrb1LTw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -1123,8 +1122,9 @@ }, "node_modules/@babel/plugin-transform-flow-strip-types": { "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.24.7.tgz", + "integrity": "sha512-cjRKJ7FobOH2eakx7Ja+KpJRj8+y+/SiB3ooYm/n2UJfxu0oEaOoxOinitkJcPqv9KxS0kxTGPUaR7L2XcXDXA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", "@babel/plugin-syntax-flow": "^7.24.7" @@ -1803,8 +1803,9 @@ }, "node_modules/@babel/preset-flow": { "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.24.7.tgz", + "integrity": "sha512-NL3Lo0NorCU607zU3NwRyJbpaB6E3t0xtd3LfAQKDfkeX4/ggcDXvkmkW42QWT5owUeW/jAe4hn+2qvkV1IbfQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", "@babel/helper-validator-option": "^7.24.7", @@ -1869,8 +1870,9 @@ }, "node_modules/@babel/register": { "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.24.6.tgz", + "integrity": "sha512-WSuFCc2wCqMeXkz/i3yfAAsxwWflEgbVkZzivgAmXl/MxrXeoYFZOOPllbC8R8WTF7u61wSRQtDVZ1879cdu6w==", "dev": true, - "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", "find-cache-dir": "^2.0.0", @@ -1887,8 +1889,9 @@ }, "node_modules/@babel/register/node_modules/find-cache-dir": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "dev": true, - "license": "MIT", "dependencies": { "commondir": "^1.0.1", "make-dir": "^2.0.0", @@ -1900,8 +1903,9 @@ }, "node_modules/@babel/register/node_modules/find-up": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, - "license": "MIT", "dependencies": { "locate-path": "^3.0.0" }, @@ -1911,8 +1915,9 @@ }, "node_modules/@babel/register/node_modules/locate-path": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, - "license": "MIT", "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -1923,8 +1928,9 @@ }, "node_modules/@babel/register/node_modules/p-locate": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, - "license": "MIT", "dependencies": { "p-limit": "^2.0.0" }, @@ -1934,16 +1940,18 @@ }, "node_modules/@babel/register/node_modules/path-exists": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/register/node_modules/pkg-dir": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, - "license": "MIT", "dependencies": { "find-up": "^3.0.0" }, @@ -2185,7 +2193,8 @@ }, "node_modules/@emotion/babel-plugin": { "version": "11.11.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", "dependencies": { "@babel/helper-module-imports": "^7.16.7", "@babel/runtime": "^7.18.3", @@ -2200,6 +2209,18 @@ "stylis": "4.2.0" } }, + "node_modules/@emotion/babel-plugin-jsx-pragmatic": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin-jsx-pragmatic/-/babel-plugin-jsx-pragmatic-0.2.1.tgz", + "integrity": "sha512-xy1SlgEJygAAIvIuC2idkGKJYa6v5iwoyILkvNKgk347bV+IImXrUat5Z86EmLGyWhEoTplVT9EHqTnHZG4HFw==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-jsx": "^7.17.12" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { "version": "1.9.0", "license": "MIT" @@ -2221,6 +2242,21 @@ "node": ">=0.10.0" } }, + "node_modules/@emotion/babel-preset-css-prop": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-preset-css-prop/-/babel-preset-css-prop-11.11.0.tgz", + "integrity": "sha512-+1Cba68IyBeltWzvbBSXcBWqP2eKQuQcSUpIu3ma4pOUeRol4EvwWrYS2Rv51aIVqg066fLB+Z9O/8NKR7uUlQ==", + "dev": true, + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.17.12", + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/babel-plugin-jsx-pragmatic": "^0.2.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@emotion/cache": { "version": "11.11.0", "license": "MIT", @@ -2296,13 +2332,78 @@ "version": "0.3.1", "license": "MIT" }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/darwin-arm64": { "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" @@ -2311,6 +2412,294 @@ "node": ">=12" } }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "dev": true, @@ -3601,37 +3990,6 @@ "@sinonjs/commons": "^3.0.0" } }, - "node_modules/@storybook/addon-actions": { - "version": "8.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/global": "^5.0.0", - "@types/uuid": "^9.0.1", - "dequal": "^2.0.2", - "polished": "^4.2.2", - "uuid": "^9.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "^8.2.2" - } - }, - "node_modules/@storybook/addon-actions/node_modules/uuid": { - "version": "9.0.1", - "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/@storybook/addon-backgrounds": { "version": "8.2.2", "dev": true, @@ -3730,6 +4088,39 @@ "storybook": "^8.2.2" } }, + "node_modules/@storybook/addon-essentials/node_modules/@storybook/addon-actions": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.2.2.tgz", + "integrity": "sha512-SN4cSRt3f0qXi5te+yhMseSdQuZntA8lGlASbRmN77YQTpIaGsNiH88xFoky0s9qz531hiRfU1R0ZSMylBwSKw==", + "dev": true, + "dependencies": { + "@storybook/global": "^5.0.0", + "@types/uuid": "^9.0.1", + "dequal": "^2.0.2", + "polished": "^4.2.2", + "uuid": "^9.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.2" + } + }, + "node_modules/@storybook/addon-essentials/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@storybook/addon-highlight": { "version": "8.2.2", "dev": true, @@ -4209,14 +4600,15 @@ } }, "node_modules/@storybook/codemod": { - "version": "8.2.3", + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-8.2.4.tgz", + "integrity": "sha512-QcZdqjX4NvkVcWR3yI9it3PfqmBOCR+3iY6j4PmG7p5IE0j9kXMKBbeFrBRprSijHKlwcjbc3bRx2SnKF6AFEg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/core": "^7.24.4", "@babel/preset-env": "^7.24.4", "@babel/types": "^7.24.0", - "@storybook/core": "8.2.3", + "@storybook/core": "8.2.4", "@storybook/csf": "0.1.11", "@types/cross-spawn": "^6.0.2", "cross-spawn": "^7.0.3", @@ -4234,8 +4626,9 @@ }, "node_modules/@storybook/codemod/node_modules/globby": { "version": "14.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", "dev": true, - "license": "MIT", "dependencies": { "@sindresorhus/merge-streams": "^2.1.0", "fast-glob": "^3.3.2", @@ -4253,8 +4646,9 @@ }, "node_modules/@storybook/codemod/node_modules/path-type": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -4264,8 +4658,9 @@ }, "node_modules/@storybook/codemod/node_modules/slash": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true, - "license": "MIT", "engines": { "node": ">=14.16" }, @@ -4274,9 +4669,10 @@ } }, "node_modules/@storybook/core": { - "version": "8.2.3", + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.2.4.tgz", + "integrity": "sha512-jePmsGZT2hhUNQs8ED6+hFVt2m4hrMseO8kkN7Mcsve1MIujzHUS7Gjo4uguBwHJJOtiXB2fw4OSiQCmsXscZA==", "dev": true, - "license": "MIT", "dependencies": { "@storybook/csf": "0.1.11", "@types/express": "^4.17.21", @@ -4320,9 +4716,10 @@ } }, "node_modules/@storybook/core/node_modules/@types/node": { - "version": "18.19.39", + "version": "18.19.40", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.40.tgz", + "integrity": "sha512-MIxieZHrm4Ee8XArBIc+Or9HINt2StOmCbgRcXGSJl8q14svRvkZPe7LJq9HKtTI1SK3wU8b91TjntUm7T69Pg==", "dev": true, - "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } @@ -5491,8 +5888,9 @@ }, "node_modules/@types/cross-spawn": { "version": "6.0.6", + "resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-fXRhhUkG4H3TQk5dBhQ7m/JDdSNHKwR2BBia62lhwEIq9xGiQKLxd6LymNhn47SjXhsUEPmxi+PKw2OkW4LLjA==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } @@ -6639,8 +7037,9 @@ }, "node_modules/ast-types": { "version": "0.16.1", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", + "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^2.0.1" }, @@ -6698,8 +7097,9 @@ }, "node_modules/babel-core": { "version": "7.0.0-bridge.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", + "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==", "dev": true, - "license": "MIT", "peerDependencies": { "@babel/core": "^7.0.0-0" } @@ -8843,9 +9243,10 @@ }, "node_modules/esbuild": { "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, - "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -8880,8 +9281,9 @@ }, "node_modules/esbuild-register": { "version": "3.5.0", + "resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.5.0.tgz", + "integrity": "sha512-+4G/XmakeBAsvJuDugJvtyF1x+XJT4FMocynNpxrvEBViirpfUn2PgNpCHedfWhF4WokNsO/OvMKrmJOIJsI5A==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.3.4" }, @@ -10185,9 +10587,10 @@ "license": "ISC" }, "node_modules/flow-parser": { - "version": "0.239.1", + "version": "0.241.0", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.241.0.tgz", + "integrity": "sha512-82yKXpz7iWknWFsognZUf5a6mBQLnVrYoYSU9Nbu7FTOpKlu3v9ehpiI9mYXuaIO3J0ojX1b83M/InXvld9HUw==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -13663,8 +14066,9 @@ }, "node_modules/jscodeshift": { "version": "0.15.2", + "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.15.2.tgz", + "integrity": "sha512-FquR7Okgmc4Sd0aEDwqho3rEiKR3BdvuG9jfdHjLJ6JQoWSMpavug3AoIfnfWhxFlf+5pzQh8qjqz0DWFrNQzA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/core": "^7.23.0", "@babel/parser": "^7.23.0", @@ -13701,8 +14105,9 @@ }, "node_modules/jscodeshift/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, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -13715,8 +14120,9 @@ }, "node_modules/jscodeshift/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -13730,8 +14136,9 @@ }, "node_modules/jscodeshift/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, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -13741,13 +14148,15 @@ }, "node_modules/jscodeshift/node_modules/color-name": { "version": "1.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/jscodeshift/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, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -13757,8 +14166,9 @@ }, "node_modules/jscodeshift/node_modules/write-file-atomic": { "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "dev": true, - "license": "ISC", "dependencies": { "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", @@ -14808,9 +15218,10 @@ }, "node_modules/msw": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.3.1.tgz", + "integrity": "sha512-ocgvBCLn/5l3jpl1lssIb3cniuACJLoOfZu01e3n5dbJrpA5PeeWn28jCLgQDNt6d7QT8tF2fYRzm9JoEHtiig==", "dev": true, "hasInstallScript": true, - "license": "MIT", "dependencies": { "@bundled-es-modules/cookie": "^2.0.0", "@bundled-es-modules/statuses": "^1.0.1", @@ -14991,8 +15402,9 @@ }, "node_modules/node-dir": { "version": "0.1.17", + "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", + "integrity": "sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==", "dev": true, - "license": "MIT", "dependencies": { "minimatch": "^3.0.2" }, @@ -15002,8 +15414,9 @@ }, "node_modules/node-dir/node_modules/brace-expansion": { "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -15011,8 +15424,9 @@ }, "node_modules/node-dir/node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -16368,8 +16782,9 @@ }, "node_modules/recast": { "version": "0.23.9", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.9.tgz", + "integrity": "sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==", "dev": true, - "license": "MIT", "dependencies": { "ast-types": "^0.16.1", "esprima": "~4.0.0", @@ -17230,14 +17645,15 @@ } }, "node_modules/storybook": { - "version": "8.2.3", + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.2.4.tgz", + "integrity": "sha512-ASavW8vIHiWpFY+4M6ngeqK5oL4OkxqdpmQYxvRqH0gA1G1hfq/vmDw4YC4GnqKwyWPQh2kaV5JFurKZVaeaDQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/core": "^7.24.4", "@babel/types": "^7.24.0", - "@storybook/codemod": "8.2.3", - "@storybook/core": "8.2.3", + "@storybook/codemod": "8.2.4", + "@storybook/core": "8.2.4", "@types/semver": "^7.3.4", "@yarnpkg/fslib": "2.10.3", "@yarnpkg/libzip": "2.3.0", @@ -18194,8 +18610,9 @@ }, "node_modules/temp": { "version": "0.8.4", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.4.tgz", + "integrity": "sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==", "dev": true, - "license": "MIT", "dependencies": { "rimraf": "~2.6.2" }, @@ -18213,8 +18630,9 @@ }, "node_modules/temp/node_modules/brace-expansion": { "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -18222,8 +18640,10 @@ }, "node_modules/temp/node_modules/glob": { "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, - "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -18241,8 +18661,9 @@ }, "node_modules/temp/node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -18252,8 +18673,10 @@ }, "node_modules/temp/node_modules/rimraf": { "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, - "license": "ISC", "dependencies": { "glob": "^7.1.3" }, diff --git a/frontend/package.json b/frontend/package.json index 25922ed2..b946e79f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -31,6 +31,7 @@ "@babel/preset-react": "^7.24.7", "@babel/preset-typescript": "^7.24.7", "@chromatic-com/storybook": "^1.6.1", + "@emotion/babel-preset-css-prop": "^11.11.0", "@storybook/addon-essentials": "^8.2.2", "@storybook/addon-interactions": "^8.2.2", "@storybook/addon-links": "^8.2.2", diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index e0b5a5d0..761405ef 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -11,6 +11,7 @@ "allowSyntheticDefaultImports": true, // default export 가 없어도 import 허용 "sourceMap": true, // 디버깅 시 어떤 파일에서 에러났는지 추적 용이 "resolveJsonModule": true, // JSON 파일 resolve + "types": ["jest", "@emotion/react/types/css-prop"], "baseUrl": ".", // 모듈 해석 기본 경로 "paths": { // 경로 별칭 설정 diff --git a/frontend/webpack.config.prod.js b/frontend/webpack.config.prod.js index 09eec58c..a0e2321b 100644 --- a/frontend/webpack.config.prod.js +++ b/frontend/webpack.config.prod.js @@ -4,6 +4,10 @@ const common = require('./webpack.config.common.js'); module.exports = merge(common, { mode: 'production', devtool: 'source-map', + devServer: { + port: 3000, + historyApiFallback: true, + }, module: { rules: [ { From 4b846218483a2eb62782c4491fc63cfefb185a4f Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Fri, 19 Jul 2024 21:15:53 +0900 Subject: [PATCH 0092/1013] =?UTF-8?q?chore:=20emotion=20css=20prop=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20storybook=EC=97=90=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?#25?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.storybook/main.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/frontend/.storybook/main.ts b/frontend/.storybook/main.ts index 13e1b260..e40e2517 100644 --- a/frontend/.storybook/main.ts +++ b/frontend/.storybook/main.ts @@ -20,6 +20,9 @@ const config: StorybookConfig = { }, }, }, + docs: { + autodocs: true, + }, swc: () => ({ jsc: { transform: { @@ -32,6 +35,15 @@ const config: StorybookConfig = { webpackFinal: async (config: Configuration) => { const { resolve } = config; + // storybook 에 emotion 관련 babel 설정추가 + config?.module?.rules?.push({ + test: /\.(ts|tsx)$/, + loader: require.resolve('babel-loader'), + options: { + presets: [require.resolve('@emotion/babel-preset-css-prop')], + }, + }); + if (resolve) { resolve.alias = { ...resolve.alias, From 6ea1248b30c2a9476710dcecc29508481ff4d70c Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Fri, 19 Jul 2024 21:24:42 +0900 Subject: [PATCH 0093/1013] =?UTF-8?q?feat:=20=EC=84=A4=EC=A0=95=EC=9D=84?= =?UTF-8?q?=20=EC=9C=84=ED=95=9C=20provider=EB=93=A4=EC=9D=84=20storybook?= =?UTF-8?q?=20decorator=EC=97=90=20=EC=B6=94=EA=B0=80=20#25?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.storybook/preview.ts | 14 -------------- frontend/.storybook/preview.tsx | 34 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 14 deletions(-) delete mode 100644 frontend/.storybook/preview.ts create mode 100644 frontend/.storybook/preview.tsx diff --git a/frontend/.storybook/preview.ts b/frontend/.storybook/preview.ts deleted file mode 100644 index adcda96b..00000000 --- a/frontend/.storybook/preview.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { Preview } from '@storybook/react'; - -const preview: Preview = { - parameters: { - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/i, - }, - }, - }, -}; - -export default preview; diff --git a/frontend/.storybook/preview.tsx b/frontend/.storybook/preview.tsx new file mode 100644 index 00000000..b11d7efd --- /dev/null +++ b/frontend/.storybook/preview.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import type { Preview } from '@storybook/react'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { MemoryRouter } from 'react-router-dom'; +import { Global, ThemeProvider } from '@emotion/react'; +import GlobalStyle from '../src/styles/GlobalStyle'; +import { Theme } from '../src/styles/Theme'; + +const queryClient = new QueryClient(); + +const preview: Preview = { + parameters: { + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i, + }, + }, + }, + decorators: [ + (Story) => ( + + + + + + + + + ), + ], +}; + +export default preview; From d70564a6cbce3c9653722cba51a625c1468fbd75 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Fri, 19 Jul 2024 21:35:14 +0900 Subject: [PATCH 0094/1013] =?UTF-8?q?design:=20peanut500=20=EC=83=89=20?= =?UTF-8?q?=EB=B0=8F=20=EB=8F=99=EC=A0=81=20=EC=8A=A4=ED=83=80=EC=9D=BC?= =?UTF-8?q?=EB=A7=81=20=EC=88=98=EC=A0=95=20#25?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/RoundVoteResult/RoundVoteResult.styled.ts | 9 +++++---- .../src/components/SelectOption/SelectOption.styled.ts | 2 +- frontend/src/components/Timer/Timer.styled.ts | 6 ++++-- frontend/src/components/common/Button/Button.styled.ts | 3 ++- frontend/src/styles/Theme.ts | 2 +- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/frontend/src/components/RoundVoteResult/RoundVoteResult.styled.ts b/frontend/src/components/RoundVoteResult/RoundVoteResult.styled.ts index b930f88d..b99fb612 100644 --- a/frontend/src/components/RoundVoteResult/RoundVoteResult.styled.ts +++ b/frontend/src/components/RoundVoteResult/RoundVoteResult.styled.ts @@ -16,11 +16,12 @@ export const layout = ({ percentage }: LayoutProps) => css` font-size: 1.2rem; background: linear-gradient( to right, - ${Theme.color.peanut400} 0%, - ${Theme.color.peanut400} ${percentage}%, - #fff4df ${percentage}%, - #fff4df 100% + ${Theme.color.peanut500} 0%, + ${Theme.color.peanut500} ${percentage - 20}%, + ${Theme.color.peanut300} ${percentage}%, + white 100% ); + border-radius: 1.7rem; `; diff --git a/frontend/src/components/SelectOption/SelectOption.styled.ts b/frontend/src/components/SelectOption/SelectOption.styled.ts index a49b9f7a..9026839b 100644 --- a/frontend/src/components/SelectOption/SelectOption.styled.ts +++ b/frontend/src/components/SelectOption/SelectOption.styled.ts @@ -10,7 +10,7 @@ export const layout = (selected: boolean) => css` height: 16.8rem; padding: 1.6rem; - background-color: ${selected ? Theme.color.peanut400 : Theme.color.peanut300}; + background-color: ${selected ? Theme.color.peanut500 : Theme.color.peanut300}; color: #000; /* 텍스트 색상 */ font-weight: bold; diff --git a/frontend/src/components/Timer/Timer.styled.ts b/frontend/src/components/Timer/Timer.styled.ts index 7e3f6242..3d8fb433 100644 --- a/frontend/src/components/Timer/Timer.styled.ts +++ b/frontend/src/components/Timer/Timer.styled.ts @@ -1,13 +1,15 @@ import { css } from '@emotion/react'; +import { Theme } from '@/styles/Theme'; + export const layout = css` display: flex; justify-content: center; width: 100%; + height: 3.2rem; flex-basis: 5%; - background: linear-gradient(to right, #ffcc6a, #fff0d4); - + background: linear-gradient(to right, ${Theme.color.peanut500}, ${Theme.color.peanut300}); border: none; border-radius: 1.7rem; `; diff --git a/frontend/src/components/common/Button/Button.styled.ts b/frontend/src/components/common/Button/Button.styled.ts index fa6cf467..f4b54269 100644 --- a/frontend/src/components/common/Button/Button.styled.ts +++ b/frontend/src/components/common/Button/Button.styled.ts @@ -1,10 +1,11 @@ import { css } from '@emotion/react'; + import { Theme } from '@/styles/Theme'; export const buttonLayout = (active: boolean) => css` padding: 1rem 4rem; - background-color: ${active ? Theme.color.peanut500 : Theme.color.peanut300}; + background-color: ${active ? Theme.color.peanut400 : Theme.color.peanut300}; font-weight: bold; font-size: 2rem; diff --git a/frontend/src/styles/Theme.ts b/frontend/src/styles/Theme.ts index 1e1de99c..fdf9bd95 100644 --- a/frontend/src/styles/Theme.ts +++ b/frontend/src/styles/Theme.ts @@ -2,7 +2,7 @@ const color = { // primary color peanut300: '#FFF4DF', peanut400: '#FFDD9A', - peanut500: '#F4BB4E', + peanut500: '#FFD076', } as const; export const Theme = { From 66173a247dc72fbaa2f1b0fec11ec3fe5ed62ca0 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Fri, 19 Jul 2024 21:37:31 +0900 Subject: [PATCH 0095/1013] =?UTF-8?q?test:=20SelectOption=20=EB=B0=8F=20Ti?= =?UTF-8?q?mer=20=EA=B8=B0=EB=B3=B8=20=EC=8A=A4=ED=86=A0=EB=A6=AC=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20#25?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SelectOption/SelectOption.stories.tsx | 37 +++++++++++++++++++ .../{Timer.stories.ts => Timer.stories.tsx} | 5 ++- 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 frontend/src/components/SelectOption/SelectOption.stories.tsx rename frontend/src/components/Timer/{Timer.stories.ts => Timer.stories.tsx} (68%) diff --git a/frontend/src/components/SelectOption/SelectOption.stories.tsx b/frontend/src/components/SelectOption/SelectOption.stories.tsx new file mode 100644 index 00000000..8f77d693 --- /dev/null +++ b/frontend/src/components/SelectOption/SelectOption.stories.tsx @@ -0,0 +1,37 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { fn } from '@storybook/test'; + +import SelectOption from './SelectOption'; + +const meta = { + title: 'SelectOption', + parameters: { + argTypes: {}, + actions: { argTypesRegex: '^on.*' }, + }, + + args: { handleSelectOption: fn() }, + + component: SelectOption, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const 선택되지_않은_옵션: Story = { + args: { + option: { content: '100억 빚 송강', optionId: 1 }, + selectedId: 0, + }, + render: ({ ...args }) => , +}; + +export const 선택된_옵션: Story = { + args: { + option: { content: '100억 빚 송강', optionId: 1 }, + selectedId: 1, + }, + + render: (args) => , +}; diff --git a/frontend/src/components/Timer/Timer.stories.ts b/frontend/src/components/Timer/Timer.stories.tsx similarity index 68% rename from frontend/src/components/Timer/Timer.stories.ts rename to frontend/src/components/Timer/Timer.stories.tsx index 4683363d..47e6f978 100644 --- a/frontend/src/components/Timer/Timer.stories.ts +++ b/frontend/src/components/Timer/Timer.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import Timer from './Timer'; const meta: Meta = { - title: 'Title', + title: 'Timer', component: Timer, }; @@ -11,6 +11,7 @@ type Story = StoryObj; export default meta; -export const Primary: Story = { +export const 기본_타이머: Story = { args: {}, + render: (args) => , }; From 5ff5dfef1de097d655ea89705ac9e6bd8de30b90 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sat, 20 Jul 2024 01:25:28 +0900 Subject: [PATCH 0096/1013] =?UTF-8?q?refactor:=20webpack=20source=20map=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=88=98=EC=A0=95=20#25?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/webpack.config.dev.js | 2 +- frontend/webpack.config.prod.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend/webpack.config.dev.js b/frontend/webpack.config.dev.js index 293ed5cf..07924b83 100644 --- a/frontend/webpack.config.dev.js +++ b/frontend/webpack.config.dev.js @@ -4,7 +4,7 @@ const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); module.exports = merge(common, { mode: 'development', - devtool: 'inline-source-map', + devtool: 'eval-source-map', devServer: { port: 3000, historyApiFallback: true, diff --git a/frontend/webpack.config.prod.js b/frontend/webpack.config.prod.js index a0e2321b..b16b8185 100644 --- a/frontend/webpack.config.prod.js +++ b/frontend/webpack.config.prod.js @@ -3,7 +3,6 @@ const common = require('./webpack.config.common.js'); module.exports = merge(common, { mode: 'production', - devtool: 'source-map', devServer: { port: 3000, historyApiFallback: true, From c5214b910a8527803174a6edaa4afce9852abb2f Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sat, 20 Jul 2024 09:32:56 +0900 Subject: [PATCH 0097/1013] =?UTF-8?q?fix:=20emotion=20babel=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20storybook=EC=97=90?= =?UTF-8?q?=EB=8F=84=20=EC=A0=81=EC=9A=A9=20#25?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.babelrc | 4 +-- frontend/.storybook/main.ts | 19 +++++++++----- frontend/package-lock.json | 51 ++++++++++++++++++++++++------------- frontend/package.json | 1 + 4 files changed, 48 insertions(+), 27 deletions(-) diff --git a/frontend/.babelrc b/frontend/.babelrc index 17323b59..5849bc03 100644 --- a/frontend/.babelrc +++ b/frontend/.babelrc @@ -9,8 +9,8 @@ "shippedProposals": true } ], - "@emotion/babel-preset-css-prop", "@babel/preset-typescript", ["@babel/preset-react", { "runtime": "automatic", "importSource": "@emotion/react" }] - ] + ], + "plugins": ["@emotion"] } diff --git a/frontend/.storybook/main.ts b/frontend/.storybook/main.ts index e40e2517..3788463e 100644 --- a/frontend/.storybook/main.ts +++ b/frontend/.storybook/main.ts @@ -33,15 +33,20 @@ const config: StorybookConfig = { }, }), webpackFinal: async (config: Configuration) => { - const { resolve } = config; + const { resolve, module } = config; - // storybook 에 emotion 관련 babel 설정추가 - config?.module?.rules?.push({ + // storybook 에 emotion 관련 babel 설정 추가 + module?.rules?.push({ test: /\.(ts|tsx)$/, - loader: require.resolve('babel-loader'), - options: { - presets: [require.resolve('@emotion/babel-preset-css-prop')], - }, + exclude: /node_modules/, + use: [ + { + loader: require.resolve('babel-loader'), + options: { + plugins: [require.resolve('@emotion/babel-plugin')], + }, + }, + ], }); if (resolve) { diff --git a/frontend/package-lock.json b/frontend/package-lock.json index b3ad8d0b..76d9fccf 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -22,6 +22,7 @@ "@babel/preset-react": "^7.24.7", "@babel/preset-typescript": "^7.24.7", "@chromatic-com/storybook": "^1.6.1", + "@emotion/babel-plugin": "^11.12.0", "@emotion/babel-preset-css-prop": "^11.11.0", "@storybook/addon-essentials": "^8.2.2", "@storybook/addon-interactions": "^8.2.2", @@ -2192,15 +2193,15 @@ } }, "node_modules/@emotion/babel-plugin": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", - "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", + "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", "dependencies": { "@babel/helper-module-imports": "^7.16.7", "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.1", - "@emotion/memoize": "^0.8.1", - "@emotion/serialize": "^1.1.2", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.2.0", "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", @@ -2221,6 +2222,11 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@emotion/babel-plugin/node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" + }, "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { "version": "1.9.0", "license": "MIT" @@ -2269,8 +2275,9 @@ } }, "node_modules/@emotion/hash": { - "version": "0.9.1", - "license": "MIT" + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==" }, "node_modules/@emotion/memoize": { "version": "0.8.1", @@ -2299,23 +2306,30 @@ } }, "node_modules/@emotion/serialize": { - "version": "1.1.4", - "license": "MIT", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.2.0.tgz", + "integrity": "sha512-X5UWpZAhGGp5LOn7OAI9k9JjRtz7nSFhZypatADcuEd/0bECZ0DzVjPdL8hljTrAku8+TjFvWIYHMOCO/0v/Ng==", "dependencies": { - "@emotion/hash": "^0.9.1", - "@emotion/memoize": "^0.8.1", - "@emotion/unitless": "^0.8.1", - "@emotion/utils": "^1.2.1", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.9.0", + "@emotion/utils": "^1.3.0", "csstype": "^3.0.2" } }, + "node_modules/@emotion/serialize/node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" + }, "node_modules/@emotion/sheet": { "version": "1.2.2", "license": "MIT" }, "node_modules/@emotion/unitless": { - "version": "0.8.1", - "license": "MIT" + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.9.0.tgz", + "integrity": "sha512-TP6GgNZtmtFaFcsOgExdnfxLLpRDla4Q66tnenA9CktvVSdNKDvMVuUah4QvWPIpNjrWsGg3qeGo9a43QooGZQ==" }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { "version": "1.0.1", @@ -2325,8 +2339,9 @@ } }, "node_modules/@emotion/utils": { - "version": "1.2.1", - "license": "MIT" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.3.0.tgz", + "integrity": "sha512-+M7u4EaX5t4bCunKTltAdGis3NFHQniikLVEQ+rPQccsX/xV4v5Etwg12paioZ9DsO+CTvimtmnjZbW85kbF8Q==" }, "node_modules/@emotion/weak-memoize": { "version": "0.3.1", diff --git a/frontend/package.json b/frontend/package.json index b946e79f..0190e9a5 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -31,6 +31,7 @@ "@babel/preset-react": "^7.24.7", "@babel/preset-typescript": "^7.24.7", "@chromatic-com/storybook": "^1.6.1", + "@emotion/babel-plugin": "^11.12.0", "@emotion/babel-preset-css-prop": "^11.11.0", "@storybook/addon-essentials": "^8.2.2", "@storybook/addon-interactions": "^8.2.2", From 2818e717dd9e7aac7840be4a83c0011378727d7d Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sat, 20 Jul 2024 09:37:40 +0900 Subject: [PATCH 0098/1013] =?UTF-8?q?chore:=20storybook=20=EA=B3=BC=20msw?= =?UTF-8?q?=20=EC=97=B0=EB=8F=99=20#25?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.storybook/main.ts | 2 +- frontend/.storybook/preview.tsx | 8 ++++++++ frontend/package-lock.json | 13 +++++++++++++ frontend/package.json | 1 + 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/frontend/.storybook/main.ts b/frontend/.storybook/main.ts index 3788463e..b2256069 100644 --- a/frontend/.storybook/main.ts +++ b/frontend/.storybook/main.ts @@ -4,9 +4,9 @@ import { Configuration } from 'webpack'; const config: StorybookConfig = { stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], + staticDirs: ['../public'], addons: [ '@storybook/addon-webpack5-compiler-swc', - '@storybook/addon-onboarding', '@storybook/addon-links', '@storybook/addon-essentials', '@chromatic-com/storybook', diff --git a/frontend/.storybook/preview.tsx b/frontend/.storybook/preview.tsx index b11d7efd..f59fdb54 100644 --- a/frontend/.storybook/preview.tsx +++ b/frontend/.storybook/preview.tsx @@ -5,11 +5,18 @@ import { MemoryRouter } from 'react-router-dom'; import { Global, ThemeProvider } from '@emotion/react'; import GlobalStyle from '../src/styles/GlobalStyle'; import { Theme } from '../src/styles/Theme'; +import { initialize, mswDecorator } from 'msw-storybook-addon'; +import { handlers } from '../src/mocks/handlers'; + +initialize(); const queryClient = new QueryClient(); const preview: Preview = { parameters: { + msw: { + handlers: [...handlers], + }, controls: { matchers: { color: /(background|color)$/i, @@ -28,6 +35,7 @@ const preview: Preview = { ), + mswDecorator, ], }; diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 76d9fccf..5b2af1f5 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -62,6 +62,7 @@ "jest-environment-jsdom": "^29.7.0", "lint-staged": "^15.2.7", "msw": "^2.3.1", + "msw-storybook-addon": "^2.0.3", "postcss-styled-syntax": "^0.6.4", "prettier": "^3.3.2", "storybook": "^8.2.2", @@ -15274,6 +15275,18 @@ } } }, + "node_modules/msw-storybook-addon": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/msw-storybook-addon/-/msw-storybook-addon-2.0.3.tgz", + "integrity": "sha512-CzHmGO32JeOPnyUnRWnB0PFTXCY1HKfHiEB/6fYoUYiFm2NYosLjzs9aBd3XJUryYEN0avJqMNh7nCRDxE5JjQ==", + "dev": true, + "dependencies": { + "is-node-process": "^1.0.1" + }, + "peerDependencies": { + "msw": "^2.0.0" + } + }, "node_modules/msw/node_modules/ansi-styles": { "version": "4.3.0", "dev": true, diff --git a/frontend/package.json b/frontend/package.json index 0190e9a5..431ee98f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -71,6 +71,7 @@ "jest-environment-jsdom": "^29.7.0", "lint-staged": "^15.2.7", "msw": "^2.3.1", + "msw-storybook-addon": "^2.0.3", "postcss-styled-syntax": "^0.6.4", "prettier": "^3.3.2", "storybook": "^8.2.2", From cbedf9a9cd7e6892c54348d7da630b5b2f06988e Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sun, 21 Jul 2024 00:14:22 +0900 Subject: [PATCH 0099/1013] =?UTF-8?q?style:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=A3=BC=EC=84=9D=20=EC=A0=9C=EA=B1=B0=20#25?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/SelectOption/SelectOption.styled.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/SelectOption/SelectOption.styled.ts b/frontend/src/components/SelectOption/SelectOption.styled.ts index 9026839b..820daf17 100644 --- a/frontend/src/components/SelectOption/SelectOption.styled.ts +++ b/frontend/src/components/SelectOption/SelectOption.styled.ts @@ -12,14 +12,14 @@ export const layout = (selected: boolean) => css` background-color: ${selected ? Theme.color.peanut500 : Theme.color.peanut300}; - color: #000; /* 텍스트 색상 */ + color: #000; font-weight: bold; font-size: 1.6rem; line-height: 2.4rem; text-align: center; word-break: keep-all; - border-radius: 3rem; /* 둥근 모서리 */ + border-radius: 3rem; transition: all 0.5s; scale: ${selected ? 1.1 : 1}; From 72b958b1876e70e6bce1827b23c3dcaf07c182ac Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sun, 21 Jul 2024 00:15:10 +0900 Subject: [PATCH 0100/1013] =?UTF-8?q?fix:=20=EB=9D=BC=EC=9D=B4=EB=B8=8C?= =?UTF-8?q?=EB=9F=AC=EB=A6=AC=20=EB=B2=84=EC=A0=84=EC=97=90=20=EC=98=81?= =?UTF-8?q?=ED=96=A5=EB=B0=9B=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20jes?= =?UTF-8?q?t=20polyfill=20=EC=88=98=EC=A0=95=20#25?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/jest.polyfills.js | 6 ++++-- frontend/package-lock.json | 22 +++++----------------- frontend/package.json | 2 +- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/frontend/jest.polyfills.js b/frontend/jest.polyfills.js index 805e8375..d35b9e9a 100644 --- a/frontend/jest.polyfills.js +++ b/frontend/jest.polyfills.js @@ -10,15 +10,18 @@ */ const { TextDecoder, TextEncoder } = require('node:util'); +const { ReadableStream, TransformStream } = require('node:stream/web'); Object.defineProperties(globalThis, { TextDecoder: { value: TextDecoder }, TextEncoder: { value: TextEncoder }, + ReadableStream: { value: ReadableStream }, + TransformStream: { value: TransformStream }, }); const { Blob, File } = require('node:buffer'); -const { fetch, Headers, FormData, Request, Response, ReadableStream } = require('undici'); +const { fetch, Headers, FormData, Request, Response } = require('undici'); Object.defineProperties(globalThis, { fetch: { value: fetch, writable: true }, @@ -28,5 +31,4 @@ Object.defineProperties(globalThis, { FormData: { value: FormData }, Request: { value: Request }, Response: { value: Response }, - ReadableStream: { value: ReadableStream }, }); diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 5b2af1f5..102f796c 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -71,7 +71,7 @@ "stylelint-order": "^6.0.4", "ts-loader": "^9.5.1", "typescript": "^5.5.3", - "undici": "^5.28.4", + "undici": "^6.19.2", "webpack": "^5.92.1", "webpack-cli": "^5.1.4", "webpack-dev-server": "^5.0.4", @@ -2802,15 +2802,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@fastify/busboy": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", - "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", - "dev": true, - "engines": { - "node": ">=14" - } - }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "dev": true, @@ -19273,15 +19264,12 @@ } }, "node_modules/undici": { - "version": "5.28.4", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", - "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", + "version": "6.19.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.2.tgz", + "integrity": "sha512-JfjKqIauur3Q6biAtHJ564e3bWa8VvT+7cSiOJHFbX4Erv6CLGDpg8z+Fmg/1OI/47RA+GI2QZaF48SSaLvyBA==", "dev": true, - "dependencies": { - "@fastify/busboy": "^2.0.0" - }, "engines": { - "node": ">=14.0" + "node": ">=18.17" } }, "node_modules/undici-types": { diff --git a/frontend/package.json b/frontend/package.json index 431ee98f..ad9fc542 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -80,7 +80,7 @@ "stylelint-order": "^6.0.4", "ts-loader": "^9.5.1", "typescript": "^5.5.3", - "undici": "^5.28.4", + "undici": "^6.19.2", "webpack": "^5.92.1", "webpack-cli": "^5.1.4", "webpack-dev-server": "^5.0.4", From 8fa23e2f6fae931efd49223955f64471b96cee6e Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sun, 21 Jul 2024 00:18:25 +0900 Subject: [PATCH 0101/1013] =?UTF-8?q?test:=20TopicContainer=20=EA=B8=B0?= =?UTF-8?q?=EB=B3=B8=20=EC=8A=A4=ED=86=A0=EB=A6=AC=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?#25?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TopicContainer/TopicContainer.stories.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 frontend/src/components/TopicContainer/TopicContainer.stories.tsx diff --git a/frontend/src/components/TopicContainer/TopicContainer.stories.tsx b/frontend/src/components/TopicContainer/TopicContainer.stories.tsx new file mode 100644 index 00000000..257e4c9b --- /dev/null +++ b/frontend/src/components/TopicContainer/TopicContainer.stories.tsx @@ -0,0 +1,16 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import TopicContainer from './TopicContainer'; + +const meta = { + title: 'TopicContainer', + component: TopicContainer, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const 기본_카테고리_및_질문: Story = { + render: (args) => , +}; From 7bb98f829e73040db3a10cfaf6adcf32f286ce9a Mon Sep 17 00:00:00 2001 From: novice0840 Date: Sun, 21 Jul 2024 03:55:52 +0900 Subject: [PATCH 0102/1013] feat: hello, world #39 --- frontend/.husky/{commit-msg => prepare-commit-msg} | 12 ++++++++---- .../src/components/TopicContainer/TopicContainer.tsx | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) rename frontend/.husky/{commit-msg => prepare-commit-msg} (68%) diff --git a/frontend/.husky/commit-msg b/frontend/.husky/prepare-commit-msg similarity index 68% rename from frontend/.husky/commit-msg rename to frontend/.husky/prepare-commit-msg index 86807a9d..c7303c4e 100644 --- a/frontend/.husky/commit-msg +++ b/frontend/.husky/prepare-commit-msg @@ -1,3 +1,5 @@ +#!/bin/sh + COMMIT_MSG_FILE=$1 COMMIT_MSG=$(cat $1) @@ -10,14 +12,16 @@ CURRENT_BRANCH=$(git branch --show-current) # 브랜치명에서 이슈 번호 추출. 브랜치명 : {prefix}/#{issue_number} ISSUE_NUMBER=$(echo $CURRENT_BRANCH | sed -n 's/.*#\([0-9]*\).*/\1/p') - if ! echo "$COMMIT_MSG" | grep -Eq "$ALLOWED_PREFIXES"; then echo "Error: Commit message does not follow the convention." echo "Allowed prefixes: feat:, fix:, refactor:, build:, docs:, chore:, test:, style:, design:, init:" exit 1 fi +# 이슈 번호가 이미 커밋 메시지에 있는지 확인 if ! echo "$COMMIT_MSG" | grep -q "#$ISSUE_NUMBER"; then - echo "Error: Commit message does not contain the issue number #$ISSUE_NUMBER." - exit 1 -fi + # 이슈 번호가 없으면 커밋 메시지 끝에 추가 + echo "$COMMIT_MSG" > $COMMIT_MSG_FILE + echo " #$ISSUE_NUMBER" >> $COMMIT_MSG_FILE + echo "Issue number #$ISSUE_NUMBER has been automatically added to the commit message." +fi \ No newline at end of file diff --git a/frontend/src/components/TopicContainer/TopicContainer.tsx b/frontend/src/components/TopicContainer/TopicContainer.tsx index d8523c04..8eeba87e 100644 --- a/frontend/src/components/TopicContainer/TopicContainer.tsx +++ b/frontend/src/components/TopicContainer/TopicContainer.tsx @@ -3,6 +3,7 @@ import { categoryText, topicLayout, topicText } from './TopicContainer.styled'; import useQuestionQuery from '@/hooks/useQuestionQuery'; const TopicContainer = () => { + console.log('hi'); const { data: question } = useQuestionQuery(); return ( From 1480b02f552f54ebd9ca9836140293cf076d1978 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Sun, 21 Jul 2024 03:58:35 +0900 Subject: [PATCH 0103/1013] =?UTF-8?q?feat:=20=EC=9D=B4=EC=8A=88=20?= =?UTF-8?q?=EB=B2=88=ED=98=B8=20=EC=9E=90=EB=8F=99=20=EB=B6=99=EC=9D=B4?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20husky=EB=A1=9C=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=20#39?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/TopicContainer/TopicContainer.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/components/TopicContainer/TopicContainer.tsx b/frontend/src/components/TopicContainer/TopicContainer.tsx index 8eeba87e..d8523c04 100644 --- a/frontend/src/components/TopicContainer/TopicContainer.tsx +++ b/frontend/src/components/TopicContainer/TopicContainer.tsx @@ -3,7 +3,6 @@ import { categoryText, topicLayout, topicText } from './TopicContainer.styled'; import useQuestionQuery from '@/hooks/useQuestionQuery'; const TopicContainer = () => { - console.log('hi'); const { data: question } = useQuestionQuery(); return ( From 9406f86bed7834a0435570ae2f4a8da3bbe430c9 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Sun, 21 Jul 2024 06:44:34 +0900 Subject: [PATCH 0104/1013] =?UTF-8?q?chore:=20pre-push=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EC=B6=94=EA=B0=80=20=20#39?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.husky/pre-push | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/frontend/.husky/pre-push b/frontend/.husky/pre-push index ecffe9c2..ce921e50 100644 --- a/frontend/.husky/pre-push +++ b/frontend/.husky/pre-push @@ -1 +1,33 @@ -cd frontend && npm run build-dev +# cd frontend && npm run build-dev + + +# 현재 브랜치 이름 가져오기 +current_branch=$(git rev-parse --abbrev-ref HEAD) + +# feat/ 로 시작하는 브랜치인지 확인 +if [[ $current_branch == feat/* ]]; then + echo "Feature branch detected: $current_branch" + echo "Starting rebase process..." + + # develop 브랜치로 전환 및 최신 변경사항 가져오기 + git checkout develop + git pull origin develop + + # 원래 브랜치로 돌아가기 + git checkout $current_branch + + # rebase 수행 + if git rebase develop; then + echo "Rebase completed successfully." + echo "Push completed." + exit 0 + else + echo "Rebase failed. Please resolve conflicts manually." + echo "After resolving conflicts, run:" + + exit 1 + fi +else + echo "Not a feature branch. Proceeding with normal push." + exit 0 +fi \ No newline at end of file From a052cef8fc0e8c72c03eb2056c313ae8cb5372fa Mon Sep 17 00:00:00 2001 From: novice0840 Date: Sun, 21 Jul 2024 06:45:59 +0900 Subject: [PATCH 0105/1013] =?UTF-8?q?chore:=20pre-push=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EC=88=98=EC=A0=95=20=20#39?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.husky/pre-push | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/.husky/pre-push b/frontend/.husky/pre-push index ce921e50..5678ec6d 100644 --- a/frontend/.husky/pre-push +++ b/frontend/.husky/pre-push @@ -1,6 +1,7 @@ # cd frontend && npm run build-dev + # 현재 브랜치 이름 가져오기 current_branch=$(git rev-parse --abbrev-ref HEAD) From 1af249db57b8a2122412c898fd1576adb256bd58 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Sun, 21 Jul 2024 07:11:53 +0900 Subject: [PATCH 0106/1013] =?UTF-8?q?chore:=20Github=20Actions=20CI=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=ED=8C=8C=EC=9D=BC=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=20#39?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/fe-ci-dev.yml | 32 ++++++++++++++++++++++++++++++++ frontend/package.json | 3 ++- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/fe-ci-dev.yml diff --git a/.github/workflows/fe-ci-dev.yml b/.github/workflows/fe-ci-dev.yml new file mode 100644 index 00000000..56c05a9c --- /dev/null +++ b/.github/workflows/fe-ci-dev.yml @@ -0,0 +1,32 @@ +name: Frontend CI + +on: + pull_request: + branches: + - develop + paths: + - "frontend/**" + +jobs: + build-and-test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: "20" + + - name: Install Dependencies + run: npm ci + working-directory: ./frontend + + - name: Build + run: npm run build-dev + working-directory: ./frontend + + - name: Test + run: npm test + working-directory: ./frontend diff --git a/frontend/package.json b/frontend/package.json index ad9fc542..e9a32bb8 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -7,7 +7,8 @@ "start": "webpack serve --config webpack.config.dev.js", "build-dev": "webpack --config webpack.config.dev.js", "build-prod": "webpack --config webpack.config.prod.js", - "test": "jest --watch", + "test": "jest", + "test:watch": "jest --watch", "lint": "npx eslint --ext .ts,.tsx .", "lint:styled": "stylelint ./src/**/*.styled.ts --fix", "prepare": "cd .. && husky frontend/.husky", From 790461a1c048085b0e8ca3d3cbce60d066cc44a9 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Sun, 21 Jul 2024 07:24:57 +0900 Subject: [PATCH 0107/1013] =?UTF-8?q?test:=20test=20sample=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=20#39?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/tests/sum.test.ts | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 frontend/src/tests/sum.test.ts diff --git a/frontend/src/tests/sum.test.ts b/frontend/src/tests/sum.test.ts new file mode 100644 index 00000000..7c40f811 --- /dev/null +++ b/frontend/src/tests/sum.test.ts @@ -0,0 +1,7 @@ +// Test Example + +const sum = (a: number, b: number) => a + b; + +test('adds 1 + 2 to equal 3', () => { + expect(sum(1, 2)).toBe(3); +}); From 4aa91ada51c321f670d59a257bb1efed06039351 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Sun, 21 Jul 2024 22:04:17 +0900 Subject: [PATCH 0108/1013] =?UTF-8?q?fix:=20CI=EC=97=90=20hotfix=20?= =?UTF-8?q?=EB=B8=8C=EB=9E=9C=EC=B9=98=20=EC=B6=94=EA=B0=80=20=20#39?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.husky/pre-push | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/.husky/pre-push b/frontend/.husky/pre-push index 5678ec6d..994b392e 100644 --- a/frontend/.husky/pre-push +++ b/frontend/.husky/pre-push @@ -6,7 +6,7 @@ current_branch=$(git rev-parse --abbrev-ref HEAD) # feat/ 로 시작하는 브랜치인지 확인 -if [[ $current_branch == feat/* ]]; then +if [[ $current_branch == feat/* ]] || [[ $current_branch == hotfix/* ]]; then echo "Feature branch detected: $current_branch" echo "Starting rebase process..." From 796de20b0338d835c8f0f49a1ce29694f18cc01c Mon Sep 17 00:00:00 2001 From: novice0840 Date: Sun, 21 Jul 2024 22:04:50 +0900 Subject: [PATCH 0109/1013] =?UTF-8?q?fix:=20actions=20version=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EB=B0=8F=20cache=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=20#39?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/fe-ci-dev.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/fe-ci-dev.yml b/.github/workflows/fe-ci-dev.yml index 56c05a9c..856df8e9 100644 --- a/.github/workflows/fe-ci-dev.yml +++ b/.github/workflows/fe-ci-dev.yml @@ -12,12 +12,13 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Use Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: "20" + cache: "npm" - name: Install Dependencies run: npm ci From 7b259e26eb63162337557479cc1b2b653858b252 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Sun, 21 Jul 2024 22:27:12 +0900 Subject: [PATCH 0110/1013] =?UTF-8?q?fix:=20actions=EC=9D=98=20npm=20cache?= =?UTF-8?q?=20=EC=97=90=20=EA=B2=BD=EB=A1=9C=20=EC=B6=94=EA=B0=80=20=20#39?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/fe-ci-dev.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/fe-ci-dev.yml b/.github/workflows/fe-ci-dev.yml index 856df8e9..e6d123ca 100644 --- a/.github/workflows/fe-ci-dev.yml +++ b/.github/workflows/fe-ci-dev.yml @@ -19,6 +19,7 @@ jobs: with: node-version: "20" cache: "npm" + working-directory: ./frontend - name: Install Dependencies run: npm ci From e4216b08a7ce254620484687998781ce1131b32b Mon Sep 17 00:00:00 2001 From: novice0840 Date: Mon, 22 Jul 2024 01:17:39 +0900 Subject: [PATCH 0111/1013] =?UTF-8?q?fix:=20action,=20babel=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95=20=20#39?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/fe-ci-dev.yml | 2 +- frontend/.babelrc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/fe-ci-dev.yml b/.github/workflows/fe-ci-dev.yml index e6d123ca..3acdba2a 100644 --- a/.github/workflows/fe-ci-dev.yml +++ b/.github/workflows/fe-ci-dev.yml @@ -19,7 +19,7 @@ jobs: with: node-version: "20" cache: "npm" - working-directory: ./frontend + cache-dependency-path: frontend/package-lock.json - name: Install Dependencies run: npm ci diff --git a/frontend/.babelrc b/frontend/.babelrc index 5849bc03..b47b0223 100644 --- a/frontend/.babelrc +++ b/frontend/.babelrc @@ -3,7 +3,7 @@ [ "@babel/preset-env", { - "targets": "> 2%, not dead", + "targets": "> 1%, not dead", "useBuiltIns": "usage", "corejs": "3.37", "shippedProposals": true From 23c19eacc42543749391e49d82f91813fad2c533 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Mon, 22 Jul 2024 01:18:51 +0900 Subject: [PATCH 0112/1013] =?UTF-8?q?fix:=20actions=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=20indent=20=EC=B6=94=EA=B0=80=20=20#39?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/fe-ci-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/fe-ci-dev.yml b/.github/workflows/fe-ci-dev.yml index 3acdba2a..3e7271fd 100644 --- a/.github/workflows/fe-ci-dev.yml +++ b/.github/workflows/fe-ci-dev.yml @@ -19,7 +19,7 @@ jobs: with: node-version: "20" cache: "npm" - cache-dependency-path: frontend/package-lock.json + cache-dependency-path: frontend/package-lock.json - name: Install Dependencies run: npm ci From 74f6b3b22d18acac3c2585e15e3a000d298bf7cf Mon Sep 17 00:00:00 2001 From: novice0840 Date: Mon, 22 Jul 2024 15:44:36 +0900 Subject: [PATCH 0113/1013] =?UTF-8?q?fix:=20husky=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=BD=ED=8A=B8=20=EC=9D=B4=EC=8A=88=20=EB=B2=88=ED=98=B8=20?= =?UTF-8?q?=EC=A4=84=20=EB=B0=94=EA=BF=88=20=EC=A0=9C=EA=B1=B0=20#41?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.husky/prepare-commit-msg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/.husky/prepare-commit-msg b/frontend/.husky/prepare-commit-msg index c7303c4e..584fc751 100644 --- a/frontend/.husky/prepare-commit-msg +++ b/frontend/.husky/prepare-commit-msg @@ -21,7 +21,7 @@ fi # 이슈 번호가 이미 커밋 메시지에 있는지 확인 if ! echo "$COMMIT_MSG" | grep -q "#$ISSUE_NUMBER"; then # 이슈 번호가 없으면 커밋 메시지 끝에 추가 - echo "$COMMIT_MSG" > $COMMIT_MSG_FILE + echo -n "$COMMIT_MSG" > $COMMIT_MSG_FILE echo " #$ISSUE_NUMBER" >> $COMMIT_MSG_FILE echo "Issue number #$ISSUE_NUMBER has been automatically added to the commit message." fi \ No newline at end of file From f774a3f09501d69993295dcef604b682fdbf928b Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Mon, 22 Jul 2024 17:29:04 +0900 Subject: [PATCH 0114/1013] =?UTF-8?q?feat:=20=EC=A7=88=EB=AC=B8=20?= =?UTF-8?q?=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20#43?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.husky/prepare-commit-msg | 6 +++--- frontend/src/mocks/data/balanceContent.json | 13 +++++++++++++ frontend/src/mocks/data/question.json | 13 ------------- .../src/types/{question.ts => balanceContent.ts} | 10 +++++----- 4 files changed, 21 insertions(+), 21 deletions(-) create mode 100644 frontend/src/mocks/data/balanceContent.json delete mode 100644 frontend/src/mocks/data/question.json rename frontend/src/types/{question.ts => balanceContent.ts} (50%) diff --git a/frontend/.husky/prepare-commit-msg b/frontend/.husky/prepare-commit-msg index 584fc751..0e6deab0 100644 --- a/frontend/.husky/prepare-commit-msg +++ b/frontend/.husky/prepare-commit-msg @@ -21,7 +21,7 @@ fi # 이슈 번호가 이미 커밋 메시지에 있는지 확인 if ! echo "$COMMIT_MSG" | grep -q "#$ISSUE_NUMBER"; then # 이슈 번호가 없으면 커밋 메시지 끝에 추가 - echo -n "$COMMIT_MSG" > $COMMIT_MSG_FILE - echo " #$ISSUE_NUMBER" >> $COMMIT_MSG_FILE + NEW_COMMIT_MSG="$COMMIT_MSG #$ISSUE_NUMBER" + echo "$NEW_COMMIT_MSG" > "$COMMIT_MSG_FILE" echo "Issue number #$ISSUE_NUMBER has been automatically added to the commit message." -fi \ No newline at end of file +fi diff --git a/frontend/src/mocks/data/balanceContent.json b/frontend/src/mocks/data/balanceContent.json new file mode 100644 index 00000000..5b1a4952 --- /dev/null +++ b/frontend/src/mocks/data/balanceContent.json @@ -0,0 +1,13 @@ +{ + "contentId": 1, + "category": "연애", + "question": "당신의 결혼 상대는?", + "firstOption": { + "optionId": 1, + "name": "100억 빚 송강" + }, + "secondOption": { + "optionId": 2, + "name": "100억 부자 송강호" + } +} diff --git a/frontend/src/mocks/data/question.json b/frontend/src/mocks/data/question.json deleted file mode 100644 index fe52b267..00000000 --- a/frontend/src/mocks/data/question.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "questionId": 1, - "category": "연애", - "title": "당신의 결혼 상대는?", - "firstOption": { - "optionId": 1, - "content": "100억 빚 송강" - }, - "secondOption": { - "optionId": 2, - "content": "100억 부자 송강호" - } -} diff --git a/frontend/src/types/question.ts b/frontend/src/types/balanceContent.ts similarity index 50% rename from frontend/src/types/question.ts rename to frontend/src/types/balanceContent.ts index 21b4a7fe..e619566c 100644 --- a/frontend/src/types/question.ts +++ b/frontend/src/types/balanceContent.ts @@ -1,13 +1,13 @@ -export interface Question { - questionId: number; - title: string; +export interface BalanceContent { + contentId: number; category: string; + question: string; firstOption: { - content: string; optionId: number; + name: string; }; secondOption: { - content: string; optionId: number; + name: string; }; } From ec6185038e6549332edc9255c1f71c4325435c8b Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Mon, 22 Jul 2024 17:43:48 +0900 Subject: [PATCH 0115/1013] =?UTF-8?q?fix:=20husky=20pre-push=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A6=BD=ED=8A=B8=EC=97=90=20=EB=B8=8C=EB=9E=9C?= =?UTF-8?q?=EC=B9=98=20=EC=A0=95=EC=B1=85=20=EC=B6=94=EA=B0=80=20#43?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.husky/pre-push | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/frontend/.husky/pre-push b/frontend/.husky/pre-push index 994b392e..60e40380 100644 --- a/frontend/.husky/pre-push +++ b/frontend/.husky/pre-push @@ -5,8 +5,23 @@ # 현재 브랜치 이름 가져오기 current_branch=$(git rev-parse --abbrev-ref HEAD) + +# 브랜치 패턴을 변수로 선언 +branch_patterns=("feat/" "hotfix/" "fix/" "refactor/" "test/") + +# 브랜치가 패턴에 맞는지 확인하는 함수 +matches_pattern() { + local branch=$1 + for pattern in "${branch_patterns[@]}"; do + if [[ $branch == $pattern* ]]; then + return 0 + fi + done + return 1 +} + # feat/ 로 시작하는 브랜치인지 확인 -if [[ $current_branch == feat/* ]] || [[ $current_branch == hotfix/* ]]; then +if matches_pattern "$current_branch"; then echo "Feature branch detected: $current_branch" echo "Starting rebase process..." @@ -31,4 +46,4 @@ if [[ $current_branch == feat/* ]] || [[ $current_branch == hotfix/* ]]; then else echo "Not a feature branch. Proceeding with normal push." exit 0 -fi \ No newline at end of file +fi From 30b717158450cec776c1d4ea34dbf915215d35c2 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Mon, 22 Jul 2024 17:45:16 +0900 Subject: [PATCH 0116/1013] =?UTF-8?q?refactor:=20content=20=EB=8F=84?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=20=EC=9A=A9=EC=96=B4=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?=EB=B0=98=EC=98=81=20#43?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/balanceContent.ts | 26 +++++++++++++++++++ frontend/src/apis/question.ts | 26 ------------------- .../SelectOption/SelectOption.stories.tsx | 4 +-- .../components/SelectOption/SelectOption.tsx | 6 ++--- frontend/src/constants/url.ts | 10 +++---- .../mocks/handlers/balanceContentHandler.ts | 11 ++++++++ frontend/src/mocks/handlers/index.ts | 4 +-- .../src/mocks/handlers/questionHandler.ts | 11 -------- frontend/src/mocks/handlers/voteHandler.ts | 4 +-- 9 files changed, 51 insertions(+), 51 deletions(-) create mode 100644 frontend/src/apis/balanceContent.ts delete mode 100644 frontend/src/apis/question.ts create mode 100644 frontend/src/mocks/handlers/balanceContentHandler.ts delete mode 100644 frontend/src/mocks/handlers/questionHandler.ts diff --git a/frontend/src/apis/balanceContent.ts b/frontend/src/apis/balanceContent.ts new file mode 100644 index 00000000..c000cb59 --- /dev/null +++ b/frontend/src/apis/balanceContent.ts @@ -0,0 +1,26 @@ +import fetcher from './fetcher'; + +import { API_URL } from '@/constants/url'; +import { BalanceContent } from '@/types/balanceContent'; + +export const fetchBalanceContent = async (roomId = 1): Promise => { + const res = await fetcher.get({ url: API_URL.balanceContent(roomId) }); + + const data = await res.json(); + + return data; +}; + +export const voteBalanceContent = async (optionId: number, roomId = 1, contentId = 1) => { + const res = await fetcher.post({ + url: API_URL.vote(roomId, contentId), + body: { + memberId: 1, + optionId, + }, + }); + + const data = await res.json(); + + return data; +}; diff --git a/frontend/src/apis/question.ts b/frontend/src/apis/question.ts deleted file mode 100644 index dd2ab0f5..00000000 --- a/frontend/src/apis/question.ts +++ /dev/null @@ -1,26 +0,0 @@ -import fetcher from './fetcher'; - -import { API_URL } from '@/constants/url'; -import { Question } from '@/types/question'; - -export const fetchQuestion = async (roomId = 1): Promise => { - const res = await fetcher.get({ url: API_URL.question(roomId) }); - - const data = await res.json(); - - return data; -}; - -export const voteQuestion = async (choiceId: number, roomId = 1, questionId = 1) => { - const res = await fetcher.post({ - url: API_URL.vote(roomId, questionId), - body: { - memberId: 1, - choiceId, - }, - }); - - const data = await res.json(); - - return data; -}; diff --git a/frontend/src/components/SelectOption/SelectOption.stories.tsx b/frontend/src/components/SelectOption/SelectOption.stories.tsx index 8f77d693..376ef2a2 100644 --- a/frontend/src/components/SelectOption/SelectOption.stories.tsx +++ b/frontend/src/components/SelectOption/SelectOption.stories.tsx @@ -21,7 +21,7 @@ type Story = StoryObj; export const 선택되지_않은_옵션: Story = { args: { - option: { content: '100억 빚 송강', optionId: 1 }, + option: { name: '100억 빚 송강', optionId: 1 }, selectedId: 0, }, render: ({ ...args }) => , @@ -29,7 +29,7 @@ export const 선택되지_않은_옵션: Story = { export const 선택된_옵션: Story = { args: { - option: { content: '100억 빚 송강', optionId: 1 }, + option: { name: '100억 빚 송강', optionId: 1 }, selectedId: 1, }, diff --git a/frontend/src/components/SelectOption/SelectOption.tsx b/frontend/src/components/SelectOption/SelectOption.tsx index 9690ff49..4070eb93 100644 --- a/frontend/src/components/SelectOption/SelectOption.tsx +++ b/frontend/src/components/SelectOption/SelectOption.tsx @@ -1,9 +1,9 @@ import { layout } from './SelectOption.styled'; -import { Question } from '@/types/question'; +import { BalanceContent } from '@/types/balanceContent'; interface SelectOptionProps { - option: Question['firstOption']; + option: BalanceContent['firstOption']; selectedId: number; handleSelectOption: (selectedId: number) => void; } @@ -14,7 +14,7 @@ const SelectOption = ({ option, selectedId, handleSelectOption }: SelectOptionPr css={layout(Boolean(selectedId === option.optionId))} onClick={() => handleSelectOption(option.optionId)} > - {option.content} + {option.name} ); }; diff --git a/frontend/src/constants/url.ts b/frontend/src/constants/url.ts index 53584e07..0200c3a8 100644 --- a/frontend/src/constants/url.ts +++ b/frontend/src/constants/url.ts @@ -1,12 +1,12 @@ const BASE_URL = process.env.NODE_ENV === 'production' ? process.env.API_BASE_URL : ''; export const API_URL = { - question: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/question`, - vote: (roomId: number, questionId: number) => - `${BASE_URL}/api/balances/rooms/${roomId}/questions/${questionId}/votes`, + balanceContent: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/content`, + vote: (roomId: number, contentId: number) => + `${BASE_URL}/api/balances/rooms/${roomId}/contents/${contentId}/votes`, }; export const MOCK_API_URL = { - question: '/api/balances/rooms/:roomId/question', - vote: '/api/balances/rooms/:roomId/questions/:questionId/votes', + balanceContent: '/api/balances/rooms/:roomId/content', + vote: '/api/balances/rooms/:roomId/contents/:contentId/votes', }; diff --git a/frontend/src/mocks/handlers/balanceContentHandler.ts b/frontend/src/mocks/handlers/balanceContentHandler.ts new file mode 100644 index 00000000..53921c9e --- /dev/null +++ b/frontend/src/mocks/handlers/balanceContentHandler.ts @@ -0,0 +1,11 @@ +import { http, HttpResponse } from 'msw'; + +import BALANCE_CONTENT from '../data/balanceContent.json'; + +import { MOCK_API_URL } from '@/constants/url'; + +const fetchBalanceContentHandler = () => { + return HttpResponse.json(BALANCE_CONTENT); +}; + +export const contentHandler = [http.get(MOCK_API_URL.balanceContent, fetchBalanceContentHandler)]; diff --git a/frontend/src/mocks/handlers/index.ts b/frontend/src/mocks/handlers/index.ts index ddef2083..05552ea8 100644 --- a/frontend/src/mocks/handlers/index.ts +++ b/frontend/src/mocks/handlers/index.ts @@ -1,4 +1,4 @@ -import { questionHandler } from './questionHandler'; +import { contentHandler } from './balanceContentHandler'; import { voteHandler } from './voteHandler'; -export const handlers = [...questionHandler, ...voteHandler]; +export const handlers = [...contentHandler, ...voteHandler]; diff --git a/frontend/src/mocks/handlers/questionHandler.ts b/frontend/src/mocks/handlers/questionHandler.ts deleted file mode 100644 index 1fd5347e..00000000 --- a/frontend/src/mocks/handlers/questionHandler.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { http, HttpResponse } from 'msw'; - -import QUESTION from '../data/question.json'; - -import { MOCK_API_URL } from '@/constants/url'; - -const fetchQuestionHandler = () => { - return HttpResponse.json(QUESTION); -}; - -export const questionHandler = [http.get(MOCK_API_URL.question, fetchQuestionHandler)]; diff --git a/frontend/src/mocks/handlers/voteHandler.ts b/frontend/src/mocks/handlers/voteHandler.ts index 4ea8caff..a8dc35b2 100644 --- a/frontend/src/mocks/handlers/voteHandler.ts +++ b/frontend/src/mocks/handlers/voteHandler.ts @@ -2,7 +2,7 @@ import { http, HttpResponse } from 'msw'; import { MOCK_API_URL } from '@/constants/url'; -const voteQuestionHandler = async ({ request }: { request: Request }) => { +const voteBalanceContentHandler = async ({ request }: { request: Request }) => { const body = await request.json(); return HttpResponse.json( @@ -13,4 +13,4 @@ const voteQuestionHandler = async ({ request }: { request: Request }) => { ); }; -export const voteHandler = [http.post(MOCK_API_URL.vote, voteQuestionHandler)]; +export const voteHandler = [http.post(MOCK_API_URL.vote, voteBalanceContentHandler)]; From 87ae571df652086a1b46dc2fc6b406f01ffb73ec Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Mon, 22 Jul 2024 17:46:04 +0900 Subject: [PATCH 0117/1013] =?UTF-8?q?refactor:=20useBalanceContentQuery=20?= =?UTF-8?q?=EC=9D=98=20data=20=EB=B0=98=ED=99=98=EA=B0=92=EC=9D=84=20balan?= =?UTF-8?q?ceContent=EB=A1=9C=20=EA=B3=A0=EC=A0=95=20#43?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/RoundVoteResult/RoundVoteResult.tsx | 8 ++++---- .../components/SelectContainer/SelectContainer.tsx | 10 +++++----- .../components/TopicContainer/TopicContainer.tsx | 8 ++++---- frontend/src/hooks/useBalanceContentQuery.ts | 14 ++++++++++++++ frontend/src/hooks/useQuestionQuery.ts | 12 ------------ 5 files changed, 27 insertions(+), 25 deletions(-) create mode 100644 frontend/src/hooks/useBalanceContentQuery.ts delete mode 100644 frontend/src/hooks/useQuestionQuery.ts diff --git a/frontend/src/components/RoundVoteResult/RoundVoteResult.tsx b/frontend/src/components/RoundVoteResult/RoundVoteResult.tsx index cd382c38..a780a118 100644 --- a/frontend/src/components/RoundVoteResult/RoundVoteResult.tsx +++ b/frontend/src/components/RoundVoteResult/RoundVoteResult.tsx @@ -1,19 +1,19 @@ import { layout, fontBold, voteContent } from './RoundVoteResult.styled'; -import useQuestionQuery from '@/hooks/useQuestionQuery'; +import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; const RoundVoteResult = () => { - const { data: question } = useQuestionQuery(); + const { balanceContent } = useBalanceContentQuery(); return (
-
{question?.firstOption.content}
+
{balanceContent?.firstOption.name}
72%
vs
-
{question?.secondOption.content}
+
{balanceContent?.secondOption.name}
28%
diff --git a/frontend/src/components/SelectContainer/SelectContainer.tsx b/frontend/src/components/SelectContainer/SelectContainer.tsx index 21f8019a..65eed145 100644 --- a/frontend/src/components/SelectContainer/SelectContainer.tsx +++ b/frontend/src/components/SelectContainer/SelectContainer.tsx @@ -5,11 +5,11 @@ import { layout, selectSection } from './SelectContainer.styled'; import Button from '@/components/common/Button/Button'; import SelectOption from '@/components/SelectOption/SelectOption'; -import useQuestionQuery from '@/hooks/useQuestionQuery'; +import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; const SelectContainer = () => { const navigate = useNavigate(); - const { data: question, isLoading } = useQuestionQuery(); + const { balanceContent, isLoading } = useBalanceContentQuery(); const [selectedId, setSelectedId] = useState(0); const goToRoundResult = () => { @@ -24,17 +24,17 @@ const SelectContainer = () => { return ( <> - {question && ( + {balanceContent && (
VS diff --git a/frontend/src/components/TopicContainer/TopicContainer.tsx b/frontend/src/components/TopicContainer/TopicContainer.tsx index d8523c04..a375be17 100644 --- a/frontend/src/components/TopicContainer/TopicContainer.tsx +++ b/frontend/src/components/TopicContainer/TopicContainer.tsx @@ -1,14 +1,14 @@ import { categoryText, topicLayout, topicText } from './TopicContainer.styled'; -import useQuestionQuery from '@/hooks/useQuestionQuery'; +import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; const TopicContainer = () => { - const { data: question } = useQuestionQuery(); + const { balanceContent } = useBalanceContentQuery(); return (
- {question?.category} - {question?.title} + {balanceContent?.category} + {balanceContent?.question}
); }; diff --git a/frontend/src/hooks/useBalanceContentQuery.ts b/frontend/src/hooks/useBalanceContentQuery.ts new file mode 100644 index 00000000..39a94531 --- /dev/null +++ b/frontend/src/hooks/useBalanceContentQuery.ts @@ -0,0 +1,14 @@ +import { useQuery } from '@tanstack/react-query'; + +import { fetchBalanceContent } from '@/apis/balanceContent'; + +const useBalanceContentQuery = () => { + const balanceContentQuery = useQuery({ + queryKey: ['balanceContent'], + queryFn: async () => await fetchBalanceContent(), + }); + + return { ...balanceContentQuery, balanceContent: balanceContentQuery.data }; +}; + +export default useBalanceContentQuery; diff --git a/frontend/src/hooks/useQuestionQuery.ts b/frontend/src/hooks/useQuestionQuery.ts deleted file mode 100644 index cb4a6f35..00000000 --- a/frontend/src/hooks/useQuestionQuery.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { useQuery } from '@tanstack/react-query'; - -import { fetchQuestion } from '@/apis/question'; - -const useQuestionQuery = () => { - return useQuery({ - queryKey: ['question'], - queryFn: async () => await fetchQuestion(), - }); -}; - -export default useQuestionQuery; From 8c4cf7e32131c241b8714f096678d6f1ac2a4eb6 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Fri, 19 Jul 2024 09:43:56 +0900 Subject: [PATCH 0118/1013] =?UTF-8?q?feat:=20RoomQuestion=EC=97=90=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EC=9D=BC=EC=9E=90=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ddangkong/domain/AuditingEntity.java | 19 +++++++++++++++++++ .../ddangkong/domain/room/RoomQuestion.java | 3 ++- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 backend/src/main/java/ddangkong/domain/AuditingEntity.java diff --git a/backend/src/main/java/ddangkong/domain/AuditingEntity.java b/backend/src/main/java/ddangkong/domain/AuditingEntity.java new file mode 100644 index 00000000..7d1bdc56 --- /dev/null +++ b/backend/src/main/java/ddangkong/domain/AuditingEntity.java @@ -0,0 +1,19 @@ +package ddangkong.domain; + +import jakarta.persistence.Column; +import jakarta.persistence.EntityListeners; +import jakarta.persistence.MappedSuperclass; +import java.time.LocalDateTime; +import lombok.Getter; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +@MappedSuperclass +@EntityListeners(AuditingEntityListener.class) +@Getter +public class AuditingEntity { + + @CreatedDate + @Column(updatable = false, nullable = false) + private LocalDateTime createdAt; +} diff --git a/backend/src/main/java/ddangkong/domain/room/RoomQuestion.java b/backend/src/main/java/ddangkong/domain/room/RoomQuestion.java index 5972d879..7315b349 100644 --- a/backend/src/main/java/ddangkong/domain/room/RoomQuestion.java +++ b/backend/src/main/java/ddangkong/domain/room/RoomQuestion.java @@ -1,5 +1,6 @@ package ddangkong.domain.room; +import ddangkong.domain.AuditingEntity; import ddangkong.domain.question.BalanceQuestion; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; @@ -19,7 +20,7 @@ @Getter @EqualsAndHashCode @ToString -public class RoomQuestion { +public class RoomQuestion extends AuditingEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) From ce1858033be75f741e9b4966fa01d8ac6c3a8d81 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Fri, 19 Jul 2024 09:45:51 +0900 Subject: [PATCH 0119/1013] =?UTF-8?q?feat:=20RoomQuestion,=20BalanceOption?= =?UTF-8?q?=EC=9D=98=20Repository=20=EA=B5=AC=ED=98=84=20#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 서비스 계층 구현시 사용할 레포지토리 구현 --- .../option/BalanceOptionRepository.java | 13 +++++++ .../room/RoomQuestionRepository.java | 12 +++++++ .../room/RoomQuestionRepositoryTest.java | 26 ++++++++++++++ backend/src/test/resources/init-test.sql | 36 +++++++++++++++++++ 4 files changed, 87 insertions(+) create mode 100644 backend/src/main/java/ddangkong/repository/option/BalanceOptionRepository.java create mode 100644 backend/src/main/java/ddangkong/repository/room/RoomQuestionRepository.java create mode 100644 backend/src/test/java/ddangkong/repository/room/RoomQuestionRepositoryTest.java create mode 100644 backend/src/test/resources/init-test.sql diff --git a/backend/src/main/java/ddangkong/repository/option/BalanceOptionRepository.java b/backend/src/main/java/ddangkong/repository/option/BalanceOptionRepository.java new file mode 100644 index 00000000..ad9462d6 --- /dev/null +++ b/backend/src/main/java/ddangkong/repository/option/BalanceOptionRepository.java @@ -0,0 +1,13 @@ +package ddangkong.repository.option; + +import ddangkong.domain.option.BalanceOption; +import ddangkong.domain.question.BalanceQuestion; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface BalanceOptionRepository extends JpaRepository { + + List findByBalanceQuestion(BalanceQuestion balanceQuestion); +} diff --git a/backend/src/main/java/ddangkong/repository/room/RoomQuestionRepository.java b/backend/src/main/java/ddangkong/repository/room/RoomQuestionRepository.java new file mode 100644 index 00000000..7d73f2b9 --- /dev/null +++ b/backend/src/main/java/ddangkong/repository/room/RoomQuestionRepository.java @@ -0,0 +1,12 @@ +package ddangkong.repository.room; + +import ddangkong.domain.room.RoomQuestion; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface RoomQuestionRepository extends JpaRepository { + + Optional findTopByRoomIdOrderByCreatedAtDesc(Long roomId); +} diff --git a/backend/src/test/java/ddangkong/repository/room/RoomQuestionRepositoryTest.java b/backend/src/test/java/ddangkong/repository/room/RoomQuestionRepositoryTest.java new file mode 100644 index 00000000..8b16d17d --- /dev/null +++ b/backend/src/test/java/ddangkong/repository/room/RoomQuestionRepositoryTest.java @@ -0,0 +1,26 @@ +package ddangkong.repository.room; + +import static org.assertj.core.api.Assertions.assertThat; + +import ddangkong.domain.room.RoomQuestion; +import ddangkong.repository.BaseRepositoryTest; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +class RoomQuestionRepositoryTest extends BaseRepositoryTest { + + @Autowired + private RoomQuestionRepository roomQuestionRepository; + + @Nested + class 방의_최신_질문_조회 { + + @Test + void 방의_가장_최신의_질문을_조회할_수_있다() { + RoomQuestion actual = roomQuestionRepository.findTopByRoomIdOrderByCreatedAtDesc(1L).get(); + + assertThat(actual.getId()).isEqualTo(1L); + } + } +} diff --git a/backend/src/test/resources/init-test.sql b/backend/src/test/resources/init-test.sql new file mode 100644 index 00000000..e9477e90 --- /dev/null +++ b/backend/src/test/resources/init-test.sql @@ -0,0 +1,36 @@ +SET REFERENTIAL_INTEGRITY FALSE; + +TRUNCATE TABLE member; +TRUNCATE TABLE balance_option; +TRUNCATE TABLE balance_question; +TRUNCATE TABLE balance_vote; +TRUNCATE TABLE room; +TRUNCATE TABLE room_question; + +ALTER TABLE member ALTER COLUMN ID RESTART WITH 1; +ALTER TABLE balance_option ALTER COLUMN ID RESTART WITH 1; +ALTER TABLE balance_question ALTER COLUMN ID RESTART WITH 1; +ALTER TABLE balance_vote ALTER COLUMN ID RESTART WITH 1; +ALTER TABLE room ALTER COLUMN ID RESTART WITH 1; +ALTER TABLE room_question ALTER COLUMN ID RESTART WITH 1; + +INSERT INTO room() VALUES (); + +INSERT INTO member(nickname, room_id) VALUES ('mohamedeu al katan', 1); +INSERT INTO member(nickname, room_id) VALUES ('deundeun ', 1); +INSERT INTO member(nickname, room_id) VALUES ('rupi', 1); +INSERT INTO member(nickname, room_id) VALUES ('rapper lee', 1); + +INSERT INTO room_question(room_id, balance_question_id, created_at) VALUES (1, 1, '2024-07-18 20:00:00.000'); + +INSERT INTO balance_question(category, content) VALUES ('EXAMPLE', '똥 맛 카레 vs 카레 맛 똥'); + +INSERT INTO balance_option(content, balance_question_id) VALUES ('똥 맛 카레', 1); +INSERT INTO balance_option(content, balance_question_id) VALUES ('카레 맛 똥', 1); + +INSERT INTO balance_vote(balance_option_id, member_id) VALUES (1, 1); +INSERT INTO balance_vote(balance_option_id, member_id) VALUES (1, 2); +INSERT INTO balance_vote(balance_option_id, member_id) VALUES (1, 3); +INSERT INTO balance_vote(balance_option_id, member_id) VALUES (2, 4); + +SET REFERENTIAL_INTEGRITY TRUE; From 54963a5a267b6f5c216bd07fd8121a2e59618259 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Fri, 19 Jul 2024 09:50:56 +0900 Subject: [PATCH 0120/1013] =?UTF-8?q?feat:=20=EB=B0=A9=20=EC=A7=88?= =?UTF-8?q?=EB=AC=B8=20=EC=A1=B0=ED=9A=8C=20=EC=84=9C=EB=B2=84=EC=8A=A4=20?= =?UTF-8?q?=EA=B3=84=EC=B8=B5=20=EA=B5=AC=ED=98=84=20#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/BusinessLogicException.java | 8 +++ .../exception/GlobalExceptionHandler.java | 20 ++++++- .../exception/ViolateDataException.java | 8 +++ .../question/BalanceQuestionService.java | 54 +++++++++++++++++++ .../repository/BaseRepositoryTest.java | 9 ++++ .../ddangkong/service/BaseServiceTest.java | 11 ++++ .../question/BalanceQuestionServiceTest.java | 44 +++++++++++++++ 7 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 backend/src/main/java/ddangkong/controller/exception/BusinessLogicException.java create mode 100644 backend/src/main/java/ddangkong/controller/exception/ViolateDataException.java create mode 100644 backend/src/main/java/ddangkong/service/question/BalanceQuestionService.java create mode 100644 backend/src/test/java/ddangkong/repository/BaseRepositoryTest.java create mode 100644 backend/src/test/java/ddangkong/service/BaseServiceTest.java create mode 100644 backend/src/test/java/ddangkong/service/question/BalanceQuestionServiceTest.java diff --git a/backend/src/main/java/ddangkong/controller/exception/BusinessLogicException.java b/backend/src/main/java/ddangkong/controller/exception/BusinessLogicException.java new file mode 100644 index 00000000..85ef4f8d --- /dev/null +++ b/backend/src/main/java/ddangkong/controller/exception/BusinessLogicException.java @@ -0,0 +1,8 @@ +package ddangkong.controller.exception; + +public class BusinessLogicException extends RuntimeException { + + public BusinessLogicException(String message) { + super(message); + } +} diff --git a/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java b/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java index 0d2c4df6..3a084fcf 100644 --- a/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java +++ b/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java @@ -12,6 +12,8 @@ @Slf4j public class GlobalExceptionHandler { + private static final String SERVER_ERROR_MESSAGE = "서버 오류가 발생했습니다. 관리자에게 문의하세요."; + @ExceptionHandler public ErrorResponse handleBindingException(BindException e) { log.warn(e.getMessage()); @@ -26,11 +28,27 @@ public ErrorResponse handleConstraintViolationException(ConstraintViolationExcep return new ErrorResponse(e.getConstraintViolations()); } + @ExceptionHandler + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ErrorResponse handleBusinessLogicException(BusinessLogicException e) { + log.warn(e.getMessage()); + + return new ErrorResponse(e.getMessage()); + } + + @ExceptionHandler + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public ErrorResponse handleViolateDataException(ViolateDataException e) { + log.warn(e.getMessage()); + + return new ErrorResponse(SERVER_ERROR_MESSAGE); + } + @ExceptionHandler @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public ErrorResponse handleException(Exception e) { log.error(e.getMessage()); - return new ErrorResponse("서버 오류가 발생했습니다. 관리자에게 문의하세요."); + return new ErrorResponse(SERVER_ERROR_MESSAGE); } } diff --git a/backend/src/main/java/ddangkong/controller/exception/ViolateDataException.java b/backend/src/main/java/ddangkong/controller/exception/ViolateDataException.java new file mode 100644 index 00000000..661eb660 --- /dev/null +++ b/backend/src/main/java/ddangkong/controller/exception/ViolateDataException.java @@ -0,0 +1,8 @@ +package ddangkong.controller.exception; + +public class ViolateDataException extends RuntimeException { + + public ViolateDataException(String message) { + super(message); + } +} diff --git a/backend/src/main/java/ddangkong/service/question/BalanceQuestionService.java b/backend/src/main/java/ddangkong/service/question/BalanceQuestionService.java new file mode 100644 index 00000000..35359203 --- /dev/null +++ b/backend/src/main/java/ddangkong/service/question/BalanceQuestionService.java @@ -0,0 +1,54 @@ +package ddangkong.service.question; + +import ddangkong.controller.exception.BusinessLogicException; +import ddangkong.controller.exception.ViolateDataException; +import ddangkong.controller.question.dto.BalanceQuestionResponse; +import ddangkong.domain.option.BalanceOption; +import ddangkong.domain.question.BalanceQuestion; +import ddangkong.repository.option.BalanceOptionRepository; +import ddangkong.repository.room.RoomQuestionRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class BalanceQuestionService { + + private static final int BALANCE_OPTION_SIZE = 2; + + private final RoomQuestionRepository roomQuestionRepository; + + private final BalanceOptionRepository balanceOptionRepository; + + @Transactional(readOnly = true) + public BalanceQuestionResponse findRecentBalanceQuestion(Long roomId) { + BalanceQuestion balanceQuestion = findRecentQuestion(roomId); + List balanceOptions = findBalanceOptions(balanceQuestion); + + return BalanceQuestionResponse.builder() + .question(balanceQuestion) + .firstOption(balanceOptions.get(0)) + .secondOption(balanceOptions.get(1)) + .build(); + } + + private BalanceQuestion findRecentQuestion(Long roomId) { + return roomQuestionRepository.findTopByRoomIdOrderByCreatedAtDesc(roomId) + .orElseThrow(() -> new BusinessLogicException("해당 방의 질문이 존재하지 않습니다.")) + .getBalanceQuestion(); + } + + private List findBalanceOptions(BalanceQuestion balanceQuestion) { + List balanceOptions = balanceOptionRepository.findByBalanceQuestion(balanceQuestion); + validateBalanceOptions(balanceOptions); + return balanceOptions; + } + + private void validateBalanceOptions(List balanceOptions) { + if (balanceOptions.size() != BALANCE_OPTION_SIZE) { + throw new ViolateDataException("밸런스 게임의 선택지가 %d개입니다".formatted(balanceOptions.size())); + } + } +} diff --git a/backend/src/test/java/ddangkong/repository/BaseRepositoryTest.java b/backend/src/test/java/ddangkong/repository/BaseRepositoryTest.java new file mode 100644 index 00000000..68a87e24 --- /dev/null +++ b/backend/src/test/java/ddangkong/repository/BaseRepositoryTest.java @@ -0,0 +1,9 @@ +package ddangkong.repository; + +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.jdbc.Sql; + +@DataJpaTest +@Sql(scripts = "/init-test.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) +public abstract class BaseRepositoryTest { +} diff --git a/backend/src/test/java/ddangkong/service/BaseServiceTest.java b/backend/src/test/java/ddangkong/service/BaseServiceTest.java new file mode 100644 index 00000000..6521e486 --- /dev/null +++ b/backend/src/test/java/ddangkong/service/BaseServiceTest.java @@ -0,0 +1,11 @@ +package ddangkong.service; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.test.context.jdbc.Sql; +import org.springframework.test.context.jdbc.Sql.ExecutionPhase; + +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@Sql(scripts = "/init-test.sql", executionPhase = ExecutionPhase.BEFORE_TEST_METHOD) +public abstract class BaseServiceTest { +} diff --git a/backend/src/test/java/ddangkong/service/question/BalanceQuestionServiceTest.java b/backend/src/test/java/ddangkong/service/question/BalanceQuestionServiceTest.java new file mode 100644 index 00000000..ec1c1945 --- /dev/null +++ b/backend/src/test/java/ddangkong/service/question/BalanceQuestionServiceTest.java @@ -0,0 +1,44 @@ +package ddangkong.service.question; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import ddangkong.controller.exception.BusinessLogicException; +import ddangkong.controller.option.dto.BalanceOptionResponse; +import ddangkong.controller.question.dto.BalanceQuestionResponse; +import ddangkong.domain.question.Category; +import ddangkong.service.BaseServiceTest; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +class BalanceQuestionServiceTest extends BaseServiceTest { + + private static final Long PROGRESS_ROOM_ID = 1L; + private static final Long NOT_EXIST_ROOM_ID = 2L; + private static final BalanceQuestionResponse BALANCE_QUESTION_RESPONSE = new BalanceQuestionResponse( + 1L, Category.EXAMPLE, "똥 맛 카레 vs 카레 맛 똥", + new BalanceOptionResponse(1L, "똥 맛 카레"), + new BalanceOptionResponse(2L, "카레 맛 똥")); + + @Autowired + private BalanceQuestionService balanceQuestionService; + + @Nested + class 방의_최신_질문_조회 { + + @Test + void 방의_최신_질문을_조회할_수_있다() { + BalanceQuestionResponse actual = balanceQuestionService.findRecentBalanceQuestion(PROGRESS_ROOM_ID); + + assertThat(actual).isEqualTo(BALANCE_QUESTION_RESPONSE); + } + + @Test + void 방이_없을_경우_예외를_던진다() { + assertThatThrownBy(() -> balanceQuestionService.findRecentBalanceQuestion(NOT_EXIST_ROOM_ID)) + .isInstanceOf(BusinessLogicException.class) + .hasMessage("해당 방의 질문이 존재하지 않습니다."); + } + } +} From 78266458dad3a82086ce42983967eb34a0aeaa64 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Fri, 19 Jul 2024 09:51:34 +0900 Subject: [PATCH 0121/1013] =?UTF-8?q?chore:=20=EC=BB=A8=ED=8A=B8=EB=A1=A4?= =?UTF-8?q?=EB=9F=AC=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EC=9C=84?= =?UTF-8?q?=ED=95=B4=20Rest-Assured=20=EC=9D=98=EC=A1=B4=EC=84=B1=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/build.gradle b/backend/build.gradle index 0a1b9a39..e57115b8 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -43,6 +43,7 @@ dependencies { testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + testImplementation 'io.rest-assured:rest-assured:5.3.1' } tasks.named('test') { From 1d30e65e4d3fabac778367f1f16bfb90d12012db Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Fri, 19 Jul 2024 09:52:45 +0900 Subject: [PATCH 0122/1013] =?UTF-8?q?feat:=20=EB=B0=A9=20=EC=A7=88?= =?UTF-8?q?=EB=AC=B8=20=EC=A1=B0=ED=9A=8C=20API=20=EA=B5=AC=ED=98=84=20#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../option/dto/BalanceOptionResponse.java | 12 +++++++ .../question/BalanceQuestionController.java | 22 ++++++++++++ .../question/dto/BalanceQuestionResponse.java | 24 +++++++++++++ .../controller/BaseControllerTest.java | 21 ++++++++++++ .../BalanceQuestionControllerTest.java | 34 +++++++++++++++++++ 5 files changed, 113 insertions(+) create mode 100644 backend/src/main/java/ddangkong/controller/option/dto/BalanceOptionResponse.java create mode 100644 backend/src/main/java/ddangkong/controller/question/BalanceQuestionController.java create mode 100644 backend/src/main/java/ddangkong/controller/question/dto/BalanceQuestionResponse.java create mode 100644 backend/src/test/java/ddangkong/controller/BaseControllerTest.java create mode 100644 backend/src/test/java/ddangkong/controller/question/BalanceQuestionControllerTest.java diff --git a/backend/src/main/java/ddangkong/controller/option/dto/BalanceOptionResponse.java b/backend/src/main/java/ddangkong/controller/option/dto/BalanceOptionResponse.java new file mode 100644 index 00000000..33e746ec --- /dev/null +++ b/backend/src/main/java/ddangkong/controller/option/dto/BalanceOptionResponse.java @@ -0,0 +1,12 @@ +package ddangkong.controller.option.dto; + +import ddangkong.domain.option.BalanceOption; + +public record BalanceOptionResponse( + Long optionId, + String content +) { + public static BalanceOptionResponse from(BalanceOption balanceOption) { + return new BalanceOptionResponse(balanceOption.getId(), balanceOption.getContent()); + } +} diff --git a/backend/src/main/java/ddangkong/controller/question/BalanceQuestionController.java b/backend/src/main/java/ddangkong/controller/question/BalanceQuestionController.java new file mode 100644 index 00000000..08897e6d --- /dev/null +++ b/backend/src/main/java/ddangkong/controller/question/BalanceQuestionController.java @@ -0,0 +1,22 @@ +package ddangkong.controller.question; + +import ddangkong.controller.question.dto.BalanceQuestionResponse; +import ddangkong.service.question.BalanceQuestionService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api") +@RequiredArgsConstructor +public class BalanceQuestionController { + + private final BalanceQuestionService balanceQuestionService; + + @GetMapping("/balances/rooms/{roomId}/question") + public BalanceQuestionResponse getBalanceQuestion(@PathVariable Long roomId) { + return balanceQuestionService.findRecentBalanceQuestion(roomId); + } +} diff --git a/backend/src/main/java/ddangkong/controller/question/dto/BalanceQuestionResponse.java b/backend/src/main/java/ddangkong/controller/question/dto/BalanceQuestionResponse.java new file mode 100644 index 00000000..e021dab8 --- /dev/null +++ b/backend/src/main/java/ddangkong/controller/question/dto/BalanceQuestionResponse.java @@ -0,0 +1,24 @@ +package ddangkong.controller.question.dto; + +import ddangkong.controller.option.dto.BalanceOptionResponse; +import ddangkong.domain.option.BalanceOption; +import ddangkong.domain.question.BalanceQuestion; +import ddangkong.domain.question.Category; +import lombok.Builder; + +public record BalanceQuestionResponse( + Long questionId, + Category category, + String title, + BalanceOptionResponse firstOption, + BalanceOptionResponse secondOption +) { + @Builder + private BalanceQuestionResponse(BalanceQuestion question, BalanceOption firstOption, BalanceOption secondOption) { + this(question.getId(), + question.getCategory(), + question.getContent(), + BalanceOptionResponse.from(firstOption), + BalanceOptionResponse.from(secondOption)); + } +} diff --git a/backend/src/test/java/ddangkong/controller/BaseControllerTest.java b/backend/src/test/java/ddangkong/controller/BaseControllerTest.java new file mode 100644 index 00000000..54a162c6 --- /dev/null +++ b/backend/src/test/java/ddangkong/controller/BaseControllerTest.java @@ -0,0 +1,21 @@ +package ddangkong.controller; + + +import io.restassured.RestAssured; +import org.junit.jupiter.api.BeforeEach; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.test.context.jdbc.Sql; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@Sql(scripts = "/init-test.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) +public abstract class BaseControllerTest { + + @LocalServerPort + private int port; + + @BeforeEach + void setUp() { + RestAssured.port = port; + } +} diff --git a/backend/src/test/java/ddangkong/controller/question/BalanceQuestionControllerTest.java b/backend/src/test/java/ddangkong/controller/question/BalanceQuestionControllerTest.java new file mode 100644 index 00000000..d09922bc --- /dev/null +++ b/backend/src/test/java/ddangkong/controller/question/BalanceQuestionControllerTest.java @@ -0,0 +1,34 @@ +package ddangkong.controller.question; + +import static org.assertj.core.api.Assertions.assertThat; + +import ddangkong.controller.BaseControllerTest; +import ddangkong.controller.option.dto.BalanceOptionResponse; +import ddangkong.controller.question.dto.BalanceQuestionResponse; +import ddangkong.domain.question.Category; +import io.restassured.RestAssured; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +class BalanceQuestionControllerTest extends BaseControllerTest { + + private static final BalanceQuestionResponse EXPECTED_RESPONSE = new BalanceQuestionResponse( + 1L, Category.EXAMPLE, "똥 맛 카레 vs 카레 맛 똥", + new BalanceOptionResponse(1L, "똥 맛 카레"), + new BalanceOptionResponse(2L, "카레 맛 똥")); + + @Nested + class 방의_질문_조회 { + + @Test + void 현재_방의_질문을_조회할_수_있다() { + BalanceQuestionResponse actual = RestAssured.given().log().all() + .when().get("/api/balances/rooms/1/question") + .then().log().all() + .statusCode(200) + .extract().as(BalanceQuestionResponse.class); + + assertThat(actual).isEqualTo(EXPECTED_RESPONSE); + } + } +} From cd745ce238f4c74cd64a47b9f72f8bbf9482c7a2 Mon Sep 17 00:00:00 2001 From: leegwichan Date: Sat, 20 Jul 2024 14:31:34 +0900 Subject: [PATCH 0123/1013] =?UTF-8?q?build:=20rest-assured=EC=9D=84=20?= =?UTF-8?q?=EC=B5=9C=EC=8B=A0=20=EB=B2=84=EC=A0=84(5.5.0)=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/build.gradle b/backend/build.gradle index e57115b8..7d6c86e2 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -43,7 +43,7 @@ dependencies { testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' - testImplementation 'io.rest-assured:rest-assured:5.3.1' + testImplementation 'io.rest-assured:rest-assured:5.5.0' } tasks.named('test') { From 4e7e634a1655ed46ea68a17bba45e56998af36f4 Mon Sep 17 00:00:00 2001 From: leegwichan Date: Sat, 20 Jul 2024 14:44:48 +0900 Subject: [PATCH 0124/1013] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=EC=BC=80=EC=9D=B4=EC=8A=A4=20=EC=9D=BC=EB=B6=80=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EB=B0=8F=20=EC=B6=94=EA=B0=80=20#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit init-test.sql에서 데이터 입력 시 한 번에 입력하도록 수정 --- .../BalanceQuestionControllerTest.java | 6 ++--- .../room/RoomQuestionRepositoryTest.java | 2 +- .../question/BalanceQuestionServiceTest.java | 6 ++--- backend/src/test/resources/init-test.sql | 22 +++++++++---------- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/backend/src/test/java/ddangkong/controller/question/BalanceQuestionControllerTest.java b/backend/src/test/java/ddangkong/controller/question/BalanceQuestionControllerTest.java index d09922bc..96aa89c0 100644 --- a/backend/src/test/java/ddangkong/controller/question/BalanceQuestionControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/question/BalanceQuestionControllerTest.java @@ -13,9 +13,9 @@ class BalanceQuestionControllerTest extends BaseControllerTest { private static final BalanceQuestionResponse EXPECTED_RESPONSE = new BalanceQuestionResponse( - 1L, Category.EXAMPLE, "똥 맛 카레 vs 카레 맛 똥", - new BalanceOptionResponse(1L, "똥 맛 카레"), - new BalanceOptionResponse(2L, "카레 맛 똥")); + 1L, Category.EXAMPLE, "민초 vs 반민초", + new BalanceOptionResponse(1L, "민초"), + new BalanceOptionResponse(2L, "반민초")); @Nested class 방의_질문_조회 { diff --git a/backend/src/test/java/ddangkong/repository/room/RoomQuestionRepositoryTest.java b/backend/src/test/java/ddangkong/repository/room/RoomQuestionRepositoryTest.java index 8b16d17d..9313697e 100644 --- a/backend/src/test/java/ddangkong/repository/room/RoomQuestionRepositoryTest.java +++ b/backend/src/test/java/ddangkong/repository/room/RoomQuestionRepositoryTest.java @@ -20,7 +20,7 @@ class 방의_최신_질문_조회 { void 방의_가장_최신의_질문을_조회할_수_있다() { RoomQuestion actual = roomQuestionRepository.findTopByRoomIdOrderByCreatedAtDesc(1L).get(); - assertThat(actual.getId()).isEqualTo(1L); + assertThat(actual.getId()).isEqualTo(2L); } } } diff --git a/backend/src/test/java/ddangkong/service/question/BalanceQuestionServiceTest.java b/backend/src/test/java/ddangkong/service/question/BalanceQuestionServiceTest.java index ec1c1945..a50efb52 100644 --- a/backend/src/test/java/ddangkong/service/question/BalanceQuestionServiceTest.java +++ b/backend/src/test/java/ddangkong/service/question/BalanceQuestionServiceTest.java @@ -17,9 +17,9 @@ class BalanceQuestionServiceTest extends BaseServiceTest { private static final Long PROGRESS_ROOM_ID = 1L; private static final Long NOT_EXIST_ROOM_ID = 2L; private static final BalanceQuestionResponse BALANCE_QUESTION_RESPONSE = new BalanceQuestionResponse( - 1L, Category.EXAMPLE, "똥 맛 카레 vs 카레 맛 똥", - new BalanceOptionResponse(1L, "똥 맛 카레"), - new BalanceOptionResponse(2L, "카레 맛 똥")); + 1L, Category.EXAMPLE, "민초 vs 반민초", + new BalanceOptionResponse(1L, "민초"), + new BalanceOptionResponse(2L, "반민초")); @Autowired private BalanceQuestionService balanceQuestionService; diff --git a/backend/src/test/resources/init-test.sql b/backend/src/test/resources/init-test.sql index e9477e90..71dbf94a 100644 --- a/backend/src/test/resources/init-test.sql +++ b/backend/src/test/resources/init-test.sql @@ -16,21 +16,19 @@ ALTER TABLE room_question ALTER COLUMN ID RESTART WITH 1; INSERT INTO room() VALUES (); -INSERT INTO member(nickname, room_id) VALUES ('mohamedeu al katan', 1); -INSERT INTO member(nickname, room_id) VALUES ('deundeun ', 1); -INSERT INTO member(nickname, room_id) VALUES ('rupi', 1); -INSERT INTO member(nickname, room_id) VALUES ('rapper lee', 1); +INSERT INTO member(nickname, room_id) +VALUES ('mohamedeu al katan', 1), ('deundeun ', 1), ('rupi', 1), ('rapper lee', 1); -INSERT INTO room_question(room_id, balance_question_id, created_at) VALUES (1, 1, '2024-07-18 20:00:00.000'); +INSERT INTO room_question(room_id, balance_question_id, created_at) +VALUES (1, 2, '2024-07-18 19:50:00.000'), (1, 1, '2024-07-18 20:00:00.000'); -INSERT INTO balance_question(category, content) VALUES ('EXAMPLE', '똥 맛 카레 vs 카레 맛 똥'); +INSERT INTO balance_question(category, content) +VALUES ('EXAMPLE', '민초 vs 반민초'), ('EXAMPLE', '월 200 백수 vs 월 500 직장인'); -INSERT INTO balance_option(content, balance_question_id) VALUES ('똥 맛 카레', 1); -INSERT INTO balance_option(content, balance_question_id) VALUES ('카레 맛 똥', 1); +INSERT INTO balance_option(content, balance_question_id) +VALUES ('민초', 1), ('반민초', 1), ('월 200 백수', 2), ('월 200 직장인', 2); -INSERT INTO balance_vote(balance_option_id, member_id) VALUES (1, 1); -INSERT INTO balance_vote(balance_option_id, member_id) VALUES (1, 2); -INSERT INTO balance_vote(balance_option_id, member_id) VALUES (1, 3); -INSERT INTO balance_vote(balance_option_id, member_id) VALUES (2, 4); +INSERT INTO balance_vote(balance_option_id, member_id) +VALUES (4, 1), (4, 2), (4, 3), (4, 4), (1, 1), (1, 2), (1, 3), (2, 4); SET REFERENTIAL_INTEGRITY TRUE; From c3cab100a677da13f1c629750b6767a2eb2e4d95 Mon Sep 17 00:00:00 2001 From: leegwichan Date: Sat, 20 Jul 2024 14:51:41 +0900 Subject: [PATCH 0125/1013] =?UTF-8?q?test:=20=EC=9D=BC=EB=B6=80=20?= =?UTF-8?q?=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=EC=9D=98=20?= =?UTF-8?q?=EA=B8=B0=EB=B3=B8=EA=B0=92=20=EB=AA=85=EC=8B=9C=ED=95=9C=20?= =?UTF-8?q?=EA=B2=83=20=EC=A0=9C=EA=B1=B0,=20ServiceTest=EC=97=90=EC=84=9C?= =?UTF-8?q?=20Mock=20=ED=99=98=EA=B2=BD=20=EC=82=AC=EC=9A=A9=20#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/java/ddangkong/controller/BaseControllerTest.java | 2 +- .../src/test/java/ddangkong/service/BaseServiceTest.java | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/backend/src/test/java/ddangkong/controller/BaseControllerTest.java b/backend/src/test/java/ddangkong/controller/BaseControllerTest.java index 54a162c6..c7516b20 100644 --- a/backend/src/test/java/ddangkong/controller/BaseControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/BaseControllerTest.java @@ -8,7 +8,7 @@ import org.springframework.test.context.jdbc.Sql; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@Sql(scripts = "/init-test.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) +@Sql(scripts = "/init-test.sql") public abstract class BaseControllerTest { @LocalServerPort diff --git a/backend/src/test/java/ddangkong/service/BaseServiceTest.java b/backend/src/test/java/ddangkong/service/BaseServiceTest.java index 6521e486..614232a7 100644 --- a/backend/src/test/java/ddangkong/service/BaseServiceTest.java +++ b/backend/src/test/java/ddangkong/service/BaseServiceTest.java @@ -1,11 +1,9 @@ package ddangkong.service; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.test.context.jdbc.Sql; -import org.springframework.test.context.jdbc.Sql.ExecutionPhase; -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -@Sql(scripts = "/init-test.sql", executionPhase = ExecutionPhase.BEFORE_TEST_METHOD) +@SpringBootTest +@Sql(scripts = "/init-test.sql") public abstract class BaseServiceTest { } From 8c37bc808dc2d6f9c3ddfbbbddaacf25179513f7 Mon Sep 17 00:00:00 2001 From: leegwichan Date: Sat, 20 Jul 2024 14:52:18 +0900 Subject: [PATCH 0126/1013] =?UTF-8?q?style:=20test=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EA=B0=9C=ED=96=89=20=EB=B0=8F=20=EB=93=A4=EC=97=AC=EC=93=B0?= =?UTF-8?q?=EA=B8=B0=20=EB=A7=9E=EC=B6=A4=20#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/test/java/ddangkong/repository/BaseRepositoryTest.java | 1 + .../ddangkong/service/question/BalanceQuestionServiceTest.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/src/test/java/ddangkong/repository/BaseRepositoryTest.java b/backend/src/test/java/ddangkong/repository/BaseRepositoryTest.java index 68a87e24..5aa0a768 100644 --- a/backend/src/test/java/ddangkong/repository/BaseRepositoryTest.java +++ b/backend/src/test/java/ddangkong/repository/BaseRepositoryTest.java @@ -6,4 +6,5 @@ @DataJpaTest @Sql(scripts = "/init-test.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) public abstract class BaseRepositoryTest { + } diff --git a/backend/src/test/java/ddangkong/service/question/BalanceQuestionServiceTest.java b/backend/src/test/java/ddangkong/service/question/BalanceQuestionServiceTest.java index a50efb52..4045a519 100644 --- a/backend/src/test/java/ddangkong/service/question/BalanceQuestionServiceTest.java +++ b/backend/src/test/java/ddangkong/service/question/BalanceQuestionServiceTest.java @@ -17,7 +17,7 @@ class BalanceQuestionServiceTest extends BaseServiceTest { private static final Long PROGRESS_ROOM_ID = 1L; private static final Long NOT_EXIST_ROOM_ID = 2L; private static final BalanceQuestionResponse BALANCE_QUESTION_RESPONSE = new BalanceQuestionResponse( - 1L, Category.EXAMPLE, "민초 vs 반민초", + 1L, Category.EXAMPLE, "민초 vs 반민초", new BalanceOptionResponse(1L, "민초"), new BalanceOptionResponse(2L, "반민초")); From ca0ecff607cba6b166aa70c9003f50322797afa4 Mon Sep 17 00:00:00 2001 From: leegwichan Date: Sat, 20 Jul 2024 15:01:01 +0900 Subject: [PATCH 0127/1013] =?UTF-8?q?refactor:=20=EC=9A=A9=EB=8F=84?= =?UTF-8?q?=EB=A5=BC=20=EB=82=98=ED=83=80=EB=82=B4=EA=B8=B0=20=EC=9C=84?= =?UTF-8?q?=ED=95=B4=20AuditingEntity=20=EC=97=90=EC=84=9C=20BaseEntity?= =?UTF-8?q?=EB=A1=9C=20=ED=8C=8C=EC=9D=BC=20=EC=9D=B4=EB=A6=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ddangkong/domain/{AuditingEntity.java => BaseEntity.java} | 2 +- backend/src/main/java/ddangkong/domain/room/RoomQuestion.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename backend/src/main/java/ddangkong/domain/{AuditingEntity.java => BaseEntity.java} (94%) diff --git a/backend/src/main/java/ddangkong/domain/AuditingEntity.java b/backend/src/main/java/ddangkong/domain/BaseEntity.java similarity index 94% rename from backend/src/main/java/ddangkong/domain/AuditingEntity.java rename to backend/src/main/java/ddangkong/domain/BaseEntity.java index 7d1bdc56..e50b1007 100644 --- a/backend/src/main/java/ddangkong/domain/AuditingEntity.java +++ b/backend/src/main/java/ddangkong/domain/BaseEntity.java @@ -11,7 +11,7 @@ @MappedSuperclass @EntityListeners(AuditingEntityListener.class) @Getter -public class AuditingEntity { +public class BaseEntity { @CreatedDate @Column(updatable = false, nullable = false) diff --git a/backend/src/main/java/ddangkong/domain/room/RoomQuestion.java b/backend/src/main/java/ddangkong/domain/room/RoomQuestion.java index 7315b349..10c2df16 100644 --- a/backend/src/main/java/ddangkong/domain/room/RoomQuestion.java +++ b/backend/src/main/java/ddangkong/domain/room/RoomQuestion.java @@ -1,6 +1,6 @@ package ddangkong.domain.room; -import ddangkong.domain.AuditingEntity; +import ddangkong.domain.BaseEntity; import ddangkong.domain.question.BalanceQuestion; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; @@ -20,7 +20,7 @@ @Getter @EqualsAndHashCode @ToString -public class RoomQuestion extends AuditingEntity { +public class RoomQuestion extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) From 4c7dfb68a461a79c7cdf6f51823eb5dd2e51115e Mon Sep 17 00:00:00 2001 From: leegwichan Date: Sat, 20 Jul 2024 15:07:21 +0900 Subject: [PATCH 0128/1013] =?UTF-8?q?refactor:=20Repository=20=EB=A5=BC=20?= =?UTF-8?q?domain=20=ED=8C=A8=ED=82=A4=EC=A7=80=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=20=EB=B0=8F=20=ED=95=84=EC=9A=94=EC=97=86=EB=8A=94=20?= =?UTF-8?q?=EC=97=90=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../option/BalanceOptionRepository.java | 5 +---- .../room => domain/question}/RoomQuestionRepository.java | 4 +--- .../ddangkong/service/question/BalanceQuestionService.java | 4 ++-- .../ddangkong/{repository => domain}/BaseRepositoryTest.java | 2 +- .../room => domain/question}/RoomQuestionRepositoryTest.java | 4 ++-- 5 files changed, 7 insertions(+), 12 deletions(-) rename backend/src/main/java/ddangkong/{repository => domain}/option/BalanceOptionRepository.java (67%) rename backend/src/main/java/ddangkong/{repository/room => domain/question}/RoomQuestionRepository.java (75%) rename backend/src/test/java/ddangkong/{repository => domain}/BaseRepositoryTest.java (90%) rename backend/src/test/java/ddangkong/{repository/room => domain/question}/RoomQuestionRepositoryTest.java (89%) diff --git a/backend/src/main/java/ddangkong/repository/option/BalanceOptionRepository.java b/backend/src/main/java/ddangkong/domain/option/BalanceOptionRepository.java similarity index 67% rename from backend/src/main/java/ddangkong/repository/option/BalanceOptionRepository.java rename to backend/src/main/java/ddangkong/domain/option/BalanceOptionRepository.java index ad9462d6..7209a1a7 100644 --- a/backend/src/main/java/ddangkong/repository/option/BalanceOptionRepository.java +++ b/backend/src/main/java/ddangkong/domain/option/BalanceOptionRepository.java @@ -1,12 +1,9 @@ -package ddangkong.repository.option; +package ddangkong.domain.option; -import ddangkong.domain.option.BalanceOption; import ddangkong.domain.question.BalanceQuestion; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; -@Repository public interface BalanceOptionRepository extends JpaRepository { List findByBalanceQuestion(BalanceQuestion balanceQuestion); diff --git a/backend/src/main/java/ddangkong/repository/room/RoomQuestionRepository.java b/backend/src/main/java/ddangkong/domain/question/RoomQuestionRepository.java similarity index 75% rename from backend/src/main/java/ddangkong/repository/room/RoomQuestionRepository.java rename to backend/src/main/java/ddangkong/domain/question/RoomQuestionRepository.java index 7d73f2b9..0006cf24 100644 --- a/backend/src/main/java/ddangkong/repository/room/RoomQuestionRepository.java +++ b/backend/src/main/java/ddangkong/domain/question/RoomQuestionRepository.java @@ -1,11 +1,9 @@ -package ddangkong.repository.room; +package ddangkong.domain.question; import ddangkong.domain.room.RoomQuestion; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; -@Repository public interface RoomQuestionRepository extends JpaRepository { Optional findTopByRoomIdOrderByCreatedAtDesc(Long roomId); diff --git a/backend/src/main/java/ddangkong/service/question/BalanceQuestionService.java b/backend/src/main/java/ddangkong/service/question/BalanceQuestionService.java index 35359203..ca787596 100644 --- a/backend/src/main/java/ddangkong/service/question/BalanceQuestionService.java +++ b/backend/src/main/java/ddangkong/service/question/BalanceQuestionService.java @@ -4,9 +4,9 @@ import ddangkong.controller.exception.ViolateDataException; import ddangkong.controller.question.dto.BalanceQuestionResponse; import ddangkong.domain.option.BalanceOption; +import ddangkong.domain.option.BalanceOptionRepository; import ddangkong.domain.question.BalanceQuestion; -import ddangkong.repository.option.BalanceOptionRepository; -import ddangkong.repository.room.RoomQuestionRepository; +import ddangkong.domain.question.RoomQuestionRepository; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; diff --git a/backend/src/test/java/ddangkong/repository/BaseRepositoryTest.java b/backend/src/test/java/ddangkong/domain/BaseRepositoryTest.java similarity index 90% rename from backend/src/test/java/ddangkong/repository/BaseRepositoryTest.java rename to backend/src/test/java/ddangkong/domain/BaseRepositoryTest.java index 5aa0a768..92a08076 100644 --- a/backend/src/test/java/ddangkong/repository/BaseRepositoryTest.java +++ b/backend/src/test/java/ddangkong/domain/BaseRepositoryTest.java @@ -1,4 +1,4 @@ -package ddangkong.repository; +package ddangkong.domain; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.test.context.jdbc.Sql; diff --git a/backend/src/test/java/ddangkong/repository/room/RoomQuestionRepositoryTest.java b/backend/src/test/java/ddangkong/domain/question/RoomQuestionRepositoryTest.java similarity index 89% rename from backend/src/test/java/ddangkong/repository/room/RoomQuestionRepositoryTest.java rename to backend/src/test/java/ddangkong/domain/question/RoomQuestionRepositoryTest.java index 9313697e..bd15ed56 100644 --- a/backend/src/test/java/ddangkong/repository/room/RoomQuestionRepositoryTest.java +++ b/backend/src/test/java/ddangkong/domain/question/RoomQuestionRepositoryTest.java @@ -1,9 +1,9 @@ -package ddangkong.repository.room; +package ddangkong.domain.question; import static org.assertj.core.api.Assertions.assertThat; +import ddangkong.domain.BaseRepositoryTest; import ddangkong.domain.room.RoomQuestion; -import ddangkong.repository.BaseRepositoryTest; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; From c039eb6f2b93822e5ed179a8abeee00d4faefd1f Mon Sep 17 00:00:00 2001 From: leegwichan Date: Sat, 20 Jul 2024 15:10:27 +0900 Subject: [PATCH 0129/1013] =?UTF-8?q?refactor:=20=EC=A7=80=EC=97=B0=20?= =?UTF-8?q?=EB=A1=9C=EB=94=A9=EC=9D=98=20=EC=97=AC=ED=8C=8C=EB=A5=BC=20?= =?UTF-8?q?=EB=A7=89=EA=B8=B0=20=EC=9C=84=ED=95=B4,=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=EC=9D=98=20@EqualsAndHashCode,=20@ToString=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0=20#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/main/java/ddangkong/domain/member/Member.java | 4 ---- .../src/main/java/ddangkong/domain/option/BalanceOption.java | 4 ---- .../main/java/ddangkong/domain/question/BalanceQuestion.java | 4 ---- backend/src/main/java/ddangkong/domain/room/Room.java | 4 ---- backend/src/main/java/ddangkong/domain/room/RoomQuestion.java | 4 ---- backend/src/main/java/ddangkong/domain/vote/BalanceVote.java | 4 ---- 6 files changed, 24 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/member/Member.java b/backend/src/main/java/ddangkong/domain/member/Member.java index 6cd46d46..9d4e59c5 100644 --- a/backend/src/main/java/ddangkong/domain/member/Member.java +++ b/backend/src/main/java/ddangkong/domain/member/Member.java @@ -10,16 +10,12 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import lombok.AccessLevel; -import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.ToString; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter -@EqualsAndHashCode -@ToString public class Member { @Id diff --git a/backend/src/main/java/ddangkong/domain/option/BalanceOption.java b/backend/src/main/java/ddangkong/domain/option/BalanceOption.java index a109ce4f..5fcc62d2 100644 --- a/backend/src/main/java/ddangkong/domain/option/BalanceOption.java +++ b/backend/src/main/java/ddangkong/domain/option/BalanceOption.java @@ -10,16 +10,12 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import lombok.AccessLevel; -import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.ToString; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter -@EqualsAndHashCode -@ToString public class BalanceOption { @Id diff --git a/backend/src/main/java/ddangkong/domain/question/BalanceQuestion.java b/backend/src/main/java/ddangkong/domain/question/BalanceQuestion.java index 20205a73..0b56e56d 100644 --- a/backend/src/main/java/ddangkong/domain/question/BalanceQuestion.java +++ b/backend/src/main/java/ddangkong/domain/question/BalanceQuestion.java @@ -8,16 +8,12 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import lombok.AccessLevel; -import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.ToString; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter -@EqualsAndHashCode -@ToString public class BalanceQuestion { @Id diff --git a/backend/src/main/java/ddangkong/domain/room/Room.java b/backend/src/main/java/ddangkong/domain/room/Room.java index 77f0cb12..9f8b1bd0 100644 --- a/backend/src/main/java/ddangkong/domain/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/room/Room.java @@ -5,16 +5,12 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import lombok.AccessLevel; -import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.ToString; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter -@EqualsAndHashCode -@ToString public class Room { @Id diff --git a/backend/src/main/java/ddangkong/domain/room/RoomQuestion.java b/backend/src/main/java/ddangkong/domain/room/RoomQuestion.java index 10c2df16..e3283839 100644 --- a/backend/src/main/java/ddangkong/domain/room/RoomQuestion.java +++ b/backend/src/main/java/ddangkong/domain/room/RoomQuestion.java @@ -10,16 +10,12 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import lombok.AccessLevel; -import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.ToString; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter -@EqualsAndHashCode -@ToString public class RoomQuestion extends BaseEntity { @Id diff --git a/backend/src/main/java/ddangkong/domain/vote/BalanceVote.java b/backend/src/main/java/ddangkong/domain/vote/BalanceVote.java index 08f8c85f..ec09a2a4 100644 --- a/backend/src/main/java/ddangkong/domain/vote/BalanceVote.java +++ b/backend/src/main/java/ddangkong/domain/vote/BalanceVote.java @@ -10,16 +10,12 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import lombok.AccessLevel; -import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.ToString; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter -@EqualsAndHashCode -@ToString public class BalanceVote { @Id From 76e819ef00e48c04fa87acaf609296f4fbc0185f Mon Sep 17 00:00:00 2001 From: leegwichan Date: Sat, 20 Jul 2024 15:12:41 +0900 Subject: [PATCH 0130/1013] =?UTF-8?q?fix:=20=EC=84=9C=EB=B2=84=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=8A=B8=EB=9E=98=ED=82=B9=EC=9D=84=20=EB=AA=85?= =?UTF-8?q?=ED=99=95=ED=9E=88=20=ED=95=98=EA=B8=B0=20=EC=9C=84=ED=95=B4,?= =?UTF-8?q?=20ViolateDataException=EC=9D=84=20error=20=EC=88=98=EC=A4=80?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=A1=9C=EA=B9=85=ED=95=A8=20#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ddangkong/controller/exception/GlobalExceptionHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java b/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java index 3a084fcf..8defc993 100644 --- a/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java +++ b/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java @@ -39,7 +39,7 @@ public ErrorResponse handleBusinessLogicException(BusinessLogicException e) { @ExceptionHandler @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public ErrorResponse handleViolateDataException(ViolateDataException e) { - log.warn(e.getMessage()); + log.error(e.getMessage()); return new ErrorResponse(SERVER_ERROR_MESSAGE); } From efc696968d417fbc24841615746f509dd32b6913 Mon Sep 17 00:00:00 2001 From: leegwichan Date: Sat, 20 Jul 2024 15:17:34 +0900 Subject: [PATCH 0131/1013] =?UTF-8?q?refactor:=20=EC=98=88=EC=99=B8?= =?UTF-8?q?=EB=A5=BC=20=EC=95=84=ED=82=A4=ED=85=8D=EC=B3=90=20=EB=8B=A8?= =?UTF-8?q?=EC=9C=84=EC=9D=98=20=ED=8C=A8=ED=82=A4=EC=A7=80=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=20#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/exception/GlobalExceptionHandler.java | 2 ++ .../excpetion}/BusinessLogicException.java | 2 +- .../exception => service/excpetion}/ViolateDataException.java | 2 +- .../ddangkong/service/question/BalanceQuestionService.java | 4 ++-- .../service/question/BalanceQuestionServiceTest.java | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) rename backend/src/main/java/ddangkong/{controller/exception => service/excpetion}/BusinessLogicException.java (78%) rename backend/src/main/java/ddangkong/{controller/exception => service/excpetion}/ViolateDataException.java (78%) diff --git a/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java b/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java index 8defc993..27def5ca 100644 --- a/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java +++ b/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java @@ -1,5 +1,7 @@ package ddangkong.controller.exception; +import ddangkong.service.excpetion.BusinessLogicException; +import ddangkong.service.excpetion.ViolateDataException; import jakarta.validation.ConstraintViolationException; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; diff --git a/backend/src/main/java/ddangkong/controller/exception/BusinessLogicException.java b/backend/src/main/java/ddangkong/service/excpetion/BusinessLogicException.java similarity index 78% rename from backend/src/main/java/ddangkong/controller/exception/BusinessLogicException.java rename to backend/src/main/java/ddangkong/service/excpetion/BusinessLogicException.java index 85ef4f8d..d2b522cb 100644 --- a/backend/src/main/java/ddangkong/controller/exception/BusinessLogicException.java +++ b/backend/src/main/java/ddangkong/service/excpetion/BusinessLogicException.java @@ -1,4 +1,4 @@ -package ddangkong.controller.exception; +package ddangkong.service.excpetion; public class BusinessLogicException extends RuntimeException { diff --git a/backend/src/main/java/ddangkong/controller/exception/ViolateDataException.java b/backend/src/main/java/ddangkong/service/excpetion/ViolateDataException.java similarity index 78% rename from backend/src/main/java/ddangkong/controller/exception/ViolateDataException.java rename to backend/src/main/java/ddangkong/service/excpetion/ViolateDataException.java index 661eb660..48192f9b 100644 --- a/backend/src/main/java/ddangkong/controller/exception/ViolateDataException.java +++ b/backend/src/main/java/ddangkong/service/excpetion/ViolateDataException.java @@ -1,4 +1,4 @@ -package ddangkong.controller.exception; +package ddangkong.service.excpetion; public class ViolateDataException extends RuntimeException { diff --git a/backend/src/main/java/ddangkong/service/question/BalanceQuestionService.java b/backend/src/main/java/ddangkong/service/question/BalanceQuestionService.java index ca787596..7ac45964 100644 --- a/backend/src/main/java/ddangkong/service/question/BalanceQuestionService.java +++ b/backend/src/main/java/ddangkong/service/question/BalanceQuestionService.java @@ -1,12 +1,12 @@ package ddangkong.service.question; -import ddangkong.controller.exception.BusinessLogicException; -import ddangkong.controller.exception.ViolateDataException; import ddangkong.controller.question.dto.BalanceQuestionResponse; import ddangkong.domain.option.BalanceOption; import ddangkong.domain.option.BalanceOptionRepository; import ddangkong.domain.question.BalanceQuestion; import ddangkong.domain.question.RoomQuestionRepository; +import ddangkong.service.excpetion.BusinessLogicException; +import ddangkong.service.excpetion.ViolateDataException; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; diff --git a/backend/src/test/java/ddangkong/service/question/BalanceQuestionServiceTest.java b/backend/src/test/java/ddangkong/service/question/BalanceQuestionServiceTest.java index 4045a519..3b30e230 100644 --- a/backend/src/test/java/ddangkong/service/question/BalanceQuestionServiceTest.java +++ b/backend/src/test/java/ddangkong/service/question/BalanceQuestionServiceTest.java @@ -3,11 +3,11 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import ddangkong.controller.exception.BusinessLogicException; import ddangkong.controller.option.dto.BalanceOptionResponse; import ddangkong.controller.question.dto.BalanceQuestionResponse; import ddangkong.domain.question.Category; import ddangkong.service.BaseServiceTest; +import ddangkong.service.excpetion.BusinessLogicException; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; From ce0f6933e9c1a8881babf65ec37b047dbffbf410 Mon Sep 17 00:00:00 2001 From: leegwichan Date: Sun, 21 Jul 2024 00:58:01 +0900 Subject: [PATCH 0132/1013] =?UTF-8?q?refactor:=20=EA=B5=AC=EB=B6=84?= =?UTF-8?q?=EC=9D=84=20=EC=89=BD=EA=B2=8C=20=ED=95=98=EA=B8=B0=20=EC=9C=84?= =?UTF-8?q?=ED=95=B4=20=EC=9D=BC=EB=B6=80=20=ED=85=8C=EC=9D=B4=EB=B8=94=20?= =?UTF-8?q?=EB=B0=8F=20=EC=BB=AC=EB=9F=BC=20=EC=9D=B4=EB=A6=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - BalanceQuestion -> BalanceContent로 변경 - 필드명 content, title 등을 name으로 바꿈 --- .../content/BalanceContentController.java | 22 +++++++++++++ .../content/dto/BalanceContentResponse.java | 27 ++++++++++++++++ .../option/dto/BalanceOptionResponse.java | 2 +- .../question/BalanceQuestionController.java | 22 ------------- .../question/dto/BalanceQuestionResponse.java | 24 -------------- .../BalanceContent.java} | 6 ++-- .../{question => content}/Category.java | 2 +- .../domain/content/RoomContentRepository.java | 10 ++++++ .../domain/option/BalanceOption.java | 8 ++--- .../option/BalanceOptionRepository.java | 4 +-- .../question/RoomQuestionRepository.java | 10 ------ .../{RoomQuestion.java => RoomContent.java} | 8 ++--- .../BalanceContentService.java} | 32 +++++++++---------- .../BalanceContentControllerTest.java} | 14 ++++---- .../RoomContentRepositoryTest.java} | 8 ++--- .../BalanceContentServiceTest.java} | 22 ++++++------- backend/src/test/resources/init-test.sql | 16 +++++----- 17 files changed, 120 insertions(+), 117 deletions(-) create mode 100644 backend/src/main/java/ddangkong/controller/content/BalanceContentController.java create mode 100644 backend/src/main/java/ddangkong/controller/content/dto/BalanceContentResponse.java delete mode 100644 backend/src/main/java/ddangkong/controller/question/BalanceQuestionController.java delete mode 100644 backend/src/main/java/ddangkong/controller/question/dto/BalanceQuestionResponse.java rename backend/src/main/java/ddangkong/domain/{question/BalanceQuestion.java => content/BalanceContent.java} (86%) rename backend/src/main/java/ddangkong/domain/{question => content}/Category.java (56%) create mode 100644 backend/src/main/java/ddangkong/domain/content/RoomContentRepository.java delete mode 100644 backend/src/main/java/ddangkong/domain/question/RoomQuestionRepository.java rename backend/src/main/java/ddangkong/domain/room/{RoomQuestion.java => RoomContent.java} (79%) rename backend/src/main/java/ddangkong/service/{question/BalanceQuestionService.java => content/BalanceContentService.java} (60%) rename backend/src/test/java/ddangkong/controller/{question/BalanceQuestionControllerTest.java => content/BalanceContentControllerTest.java} (63%) rename backend/src/test/java/ddangkong/domain/{question/RoomQuestionRepositoryTest.java => content/RoomContentRepositoryTest.java} (68%) rename backend/src/test/java/ddangkong/service/{question/BalanceQuestionServiceTest.java => content/BalanceContentServiceTest.java} (56%) diff --git a/backend/src/main/java/ddangkong/controller/content/BalanceContentController.java b/backend/src/main/java/ddangkong/controller/content/BalanceContentController.java new file mode 100644 index 00000000..495d6752 --- /dev/null +++ b/backend/src/main/java/ddangkong/controller/content/BalanceContentController.java @@ -0,0 +1,22 @@ +package ddangkong.controller.content; + +import ddangkong.controller.content.dto.BalanceContentResponse; +import ddangkong.service.content.BalanceContentService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api") +@RequiredArgsConstructor +public class BalanceContentController { + + private final BalanceContentService balanceContentService; + + @GetMapping("/balances/rooms/{roomId}/question") + public BalanceContentResponse getBalanceContent(@PathVariable Long roomId) { + return balanceContentService.findRecentBalanceContent(roomId); + } +} diff --git a/backend/src/main/java/ddangkong/controller/content/dto/BalanceContentResponse.java b/backend/src/main/java/ddangkong/controller/content/dto/BalanceContentResponse.java new file mode 100644 index 00000000..74c26770 --- /dev/null +++ b/backend/src/main/java/ddangkong/controller/content/dto/BalanceContentResponse.java @@ -0,0 +1,27 @@ +package ddangkong.controller.content.dto; + +import ddangkong.controller.option.dto.BalanceOptionResponse; +import ddangkong.domain.content.BalanceContent; +import ddangkong.domain.content.Category; +import ddangkong.domain.option.BalanceOption; +import lombok.Builder; + +public record BalanceContentResponse( + Long questionId, + Category category, + String title, + BalanceOptionResponse firstOption, + BalanceOptionResponse secondOption +) { + + @Builder + private BalanceContentResponse(BalanceContent balanceContent, + BalanceOption firstOption, + BalanceOption secondOption) { + this(balanceContent.getId(), + balanceContent.getCategory(), + balanceContent.getName(), + BalanceOptionResponse.from(firstOption), + BalanceOptionResponse.from(secondOption)); + } +} diff --git a/backend/src/main/java/ddangkong/controller/option/dto/BalanceOptionResponse.java b/backend/src/main/java/ddangkong/controller/option/dto/BalanceOptionResponse.java index 33e746ec..665562cd 100644 --- a/backend/src/main/java/ddangkong/controller/option/dto/BalanceOptionResponse.java +++ b/backend/src/main/java/ddangkong/controller/option/dto/BalanceOptionResponse.java @@ -7,6 +7,6 @@ public record BalanceOptionResponse( String content ) { public static BalanceOptionResponse from(BalanceOption balanceOption) { - return new BalanceOptionResponse(balanceOption.getId(), balanceOption.getContent()); + return new BalanceOptionResponse(balanceOption.getId(), balanceOption.getName()); } } diff --git a/backend/src/main/java/ddangkong/controller/question/BalanceQuestionController.java b/backend/src/main/java/ddangkong/controller/question/BalanceQuestionController.java deleted file mode 100644 index 08897e6d..00000000 --- a/backend/src/main/java/ddangkong/controller/question/BalanceQuestionController.java +++ /dev/null @@ -1,22 +0,0 @@ -package ddangkong.controller.question; - -import ddangkong.controller.question.dto.BalanceQuestionResponse; -import ddangkong.service.question.BalanceQuestionService; -import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/api") -@RequiredArgsConstructor -public class BalanceQuestionController { - - private final BalanceQuestionService balanceQuestionService; - - @GetMapping("/balances/rooms/{roomId}/question") - public BalanceQuestionResponse getBalanceQuestion(@PathVariable Long roomId) { - return balanceQuestionService.findRecentBalanceQuestion(roomId); - } -} diff --git a/backend/src/main/java/ddangkong/controller/question/dto/BalanceQuestionResponse.java b/backend/src/main/java/ddangkong/controller/question/dto/BalanceQuestionResponse.java deleted file mode 100644 index e021dab8..00000000 --- a/backend/src/main/java/ddangkong/controller/question/dto/BalanceQuestionResponse.java +++ /dev/null @@ -1,24 +0,0 @@ -package ddangkong.controller.question.dto; - -import ddangkong.controller.option.dto.BalanceOptionResponse; -import ddangkong.domain.option.BalanceOption; -import ddangkong.domain.question.BalanceQuestion; -import ddangkong.domain.question.Category; -import lombok.Builder; - -public record BalanceQuestionResponse( - Long questionId, - Category category, - String title, - BalanceOptionResponse firstOption, - BalanceOptionResponse secondOption -) { - @Builder - private BalanceQuestionResponse(BalanceQuestion question, BalanceOption firstOption, BalanceOption secondOption) { - this(question.getId(), - question.getCategory(), - question.getContent(), - BalanceOptionResponse.from(firstOption), - BalanceOptionResponse.from(secondOption)); - } -} diff --git a/backend/src/main/java/ddangkong/domain/question/BalanceQuestion.java b/backend/src/main/java/ddangkong/domain/content/BalanceContent.java similarity index 86% rename from backend/src/main/java/ddangkong/domain/question/BalanceQuestion.java rename to backend/src/main/java/ddangkong/domain/content/BalanceContent.java index 0b56e56d..bb223821 100644 --- a/backend/src/main/java/ddangkong/domain/question/BalanceQuestion.java +++ b/backend/src/main/java/ddangkong/domain/content/BalanceContent.java @@ -1,4 +1,4 @@ -package ddangkong.domain.question; +package ddangkong.domain.content; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -14,7 +14,7 @@ @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter -public class BalanceQuestion { +public class BalanceContent { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -25,5 +25,5 @@ public class BalanceQuestion { private Category category; @Column(nullable = false) - private String content; + private String name; } diff --git a/backend/src/main/java/ddangkong/domain/question/Category.java b/backend/src/main/java/ddangkong/domain/content/Category.java similarity index 56% rename from backend/src/main/java/ddangkong/domain/question/Category.java rename to backend/src/main/java/ddangkong/domain/content/Category.java index fe67d4c5..ba69a0a0 100644 --- a/backend/src/main/java/ddangkong/domain/question/Category.java +++ b/backend/src/main/java/ddangkong/domain/content/Category.java @@ -1,4 +1,4 @@ -package ddangkong.domain.question; +package ddangkong.domain.content; public enum Category { EXAMPLE, diff --git a/backend/src/main/java/ddangkong/domain/content/RoomContentRepository.java b/backend/src/main/java/ddangkong/domain/content/RoomContentRepository.java new file mode 100644 index 00000000..bd20d71c --- /dev/null +++ b/backend/src/main/java/ddangkong/domain/content/RoomContentRepository.java @@ -0,0 +1,10 @@ +package ddangkong.domain.content; + +import ddangkong.domain.room.RoomContent; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface RoomContentRepository extends JpaRepository { + + Optional findTopByRoomIdOrderByCreatedAtDesc(Long roomId); +} diff --git a/backend/src/main/java/ddangkong/domain/option/BalanceOption.java b/backend/src/main/java/ddangkong/domain/option/BalanceOption.java index 5fcc62d2..894e22e6 100644 --- a/backend/src/main/java/ddangkong/domain/option/BalanceOption.java +++ b/backend/src/main/java/ddangkong/domain/option/BalanceOption.java @@ -1,6 +1,6 @@ package ddangkong.domain.option; -import ddangkong.domain.question.BalanceQuestion; +import ddangkong.domain.content.BalanceContent; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; @@ -23,9 +23,9 @@ public class BalanceOption { private Long id; @Column(nullable = false) - private String content; + private String name; @ManyToOne(optional = false, fetch = FetchType.LAZY) - @JoinColumn(name = "balance_question_id", nullable = false) - private BalanceQuestion balanceQuestion; + @JoinColumn(name = "balance_content_id", nullable = false) + private BalanceContent balanceContent; } diff --git a/backend/src/main/java/ddangkong/domain/option/BalanceOptionRepository.java b/backend/src/main/java/ddangkong/domain/option/BalanceOptionRepository.java index 7209a1a7..7635ab60 100644 --- a/backend/src/main/java/ddangkong/domain/option/BalanceOptionRepository.java +++ b/backend/src/main/java/ddangkong/domain/option/BalanceOptionRepository.java @@ -1,10 +1,10 @@ package ddangkong.domain.option; -import ddangkong.domain.question.BalanceQuestion; +import ddangkong.domain.content.BalanceContent; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; public interface BalanceOptionRepository extends JpaRepository { - List findByBalanceQuestion(BalanceQuestion balanceQuestion); + List findByBalanceContent(BalanceContent balanceContent); } diff --git a/backend/src/main/java/ddangkong/domain/question/RoomQuestionRepository.java b/backend/src/main/java/ddangkong/domain/question/RoomQuestionRepository.java deleted file mode 100644 index 0006cf24..00000000 --- a/backend/src/main/java/ddangkong/domain/question/RoomQuestionRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package ddangkong.domain.question; - -import ddangkong.domain.room.RoomQuestion; -import java.util.Optional; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface RoomQuestionRepository extends JpaRepository { - - Optional findTopByRoomIdOrderByCreatedAtDesc(Long roomId); -} diff --git a/backend/src/main/java/ddangkong/domain/room/RoomQuestion.java b/backend/src/main/java/ddangkong/domain/room/RoomContent.java similarity index 79% rename from backend/src/main/java/ddangkong/domain/room/RoomQuestion.java rename to backend/src/main/java/ddangkong/domain/room/RoomContent.java index e3283839..b9508e77 100644 --- a/backend/src/main/java/ddangkong/domain/room/RoomQuestion.java +++ b/backend/src/main/java/ddangkong/domain/room/RoomContent.java @@ -1,7 +1,7 @@ package ddangkong.domain.room; import ddangkong.domain.BaseEntity; -import ddangkong.domain.question.BalanceQuestion; +import ddangkong.domain.content.BalanceContent; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; @@ -16,7 +16,7 @@ @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter -public class RoomQuestion extends BaseEntity { +public class RoomContent extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -27,6 +27,6 @@ public class RoomQuestion extends BaseEntity { private Room room; @ManyToOne(optional = false, fetch = FetchType.LAZY) - @JoinColumn(name = "balance_question_id") - private BalanceQuestion balanceQuestion; + @JoinColumn(name = "balance_content_id") + private BalanceContent balanceContent; } diff --git a/backend/src/main/java/ddangkong/service/question/BalanceQuestionService.java b/backend/src/main/java/ddangkong/service/content/BalanceContentService.java similarity index 60% rename from backend/src/main/java/ddangkong/service/question/BalanceQuestionService.java rename to backend/src/main/java/ddangkong/service/content/BalanceContentService.java index 7ac45964..a87ae3a4 100644 --- a/backend/src/main/java/ddangkong/service/question/BalanceQuestionService.java +++ b/backend/src/main/java/ddangkong/service/content/BalanceContentService.java @@ -1,10 +1,10 @@ -package ddangkong.service.question; +package ddangkong.service.content; -import ddangkong.controller.question.dto.BalanceQuestionResponse; +import ddangkong.controller.content.dto.BalanceContentResponse; import ddangkong.domain.option.BalanceOption; import ddangkong.domain.option.BalanceOptionRepository; -import ddangkong.domain.question.BalanceQuestion; -import ddangkong.domain.question.RoomQuestionRepository; +import ddangkong.domain.content.BalanceContent; +import ddangkong.domain.content.RoomContentRepository; import ddangkong.service.excpetion.BusinessLogicException; import ddangkong.service.excpetion.ViolateDataException; import java.util.List; @@ -14,34 +14,34 @@ @Service @RequiredArgsConstructor -public class BalanceQuestionService { +public class BalanceContentService { private static final int BALANCE_OPTION_SIZE = 2; - private final RoomQuestionRepository roomQuestionRepository; + private final RoomContentRepository roomContentRepository; private final BalanceOptionRepository balanceOptionRepository; @Transactional(readOnly = true) - public BalanceQuestionResponse findRecentBalanceQuestion(Long roomId) { - BalanceQuestion balanceQuestion = findRecentQuestion(roomId); - List balanceOptions = findBalanceOptions(balanceQuestion); + public BalanceContentResponse findRecentBalanceContent(Long roomId) { + BalanceContent balanceContent = findRecentContent(roomId); + List balanceOptions = findBalanceOptions(balanceContent); - return BalanceQuestionResponse.builder() - .question(balanceQuestion) + return BalanceContentResponse.builder() + .balanceContent(balanceContent) .firstOption(balanceOptions.get(0)) .secondOption(balanceOptions.get(1)) .build(); } - private BalanceQuestion findRecentQuestion(Long roomId) { - return roomQuestionRepository.findTopByRoomIdOrderByCreatedAtDesc(roomId) + private BalanceContent findRecentContent(Long roomId) { + return roomContentRepository.findTopByRoomIdOrderByCreatedAtDesc(roomId) .orElseThrow(() -> new BusinessLogicException("해당 방의 질문이 존재하지 않습니다.")) - .getBalanceQuestion(); + .getBalanceContent(); } - private List findBalanceOptions(BalanceQuestion balanceQuestion) { - List balanceOptions = balanceOptionRepository.findByBalanceQuestion(balanceQuestion); + private List findBalanceOptions(BalanceContent balanceContent) { + List balanceOptions = balanceOptionRepository.findByBalanceContent(balanceContent); validateBalanceOptions(balanceOptions); return balanceOptions; } diff --git a/backend/src/test/java/ddangkong/controller/question/BalanceQuestionControllerTest.java b/backend/src/test/java/ddangkong/controller/content/BalanceContentControllerTest.java similarity index 63% rename from backend/src/test/java/ddangkong/controller/question/BalanceQuestionControllerTest.java rename to backend/src/test/java/ddangkong/controller/content/BalanceContentControllerTest.java index 96aa89c0..99107635 100644 --- a/backend/src/test/java/ddangkong/controller/question/BalanceQuestionControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/content/BalanceContentControllerTest.java @@ -1,18 +1,18 @@ -package ddangkong.controller.question; +package ddangkong.controller.content; import static org.assertj.core.api.Assertions.assertThat; import ddangkong.controller.BaseControllerTest; import ddangkong.controller.option.dto.BalanceOptionResponse; -import ddangkong.controller.question.dto.BalanceQuestionResponse; -import ddangkong.domain.question.Category; +import ddangkong.controller.content.dto.BalanceContentResponse; +import ddangkong.domain.content.Category; import io.restassured.RestAssured; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -class BalanceQuestionControllerTest extends BaseControllerTest { +class BalanceContentControllerTest extends BaseControllerTest { - private static final BalanceQuestionResponse EXPECTED_RESPONSE = new BalanceQuestionResponse( + private static final BalanceContentResponse EXPECTED_RESPONSE = new BalanceContentResponse( 1L, Category.EXAMPLE, "민초 vs 반민초", new BalanceOptionResponse(1L, "민초"), new BalanceOptionResponse(2L, "반민초")); @@ -22,11 +22,11 @@ class 방의_질문_조회 { @Test void 현재_방의_질문을_조회할_수_있다() { - BalanceQuestionResponse actual = RestAssured.given().log().all() + BalanceContentResponse actual = RestAssured.given().log().all() .when().get("/api/balances/rooms/1/question") .then().log().all() .statusCode(200) - .extract().as(BalanceQuestionResponse.class); + .extract().as(BalanceContentResponse.class); assertThat(actual).isEqualTo(EXPECTED_RESPONSE); } diff --git a/backend/src/test/java/ddangkong/domain/question/RoomQuestionRepositoryTest.java b/backend/src/test/java/ddangkong/domain/content/RoomContentRepositoryTest.java similarity index 68% rename from backend/src/test/java/ddangkong/domain/question/RoomQuestionRepositoryTest.java rename to backend/src/test/java/ddangkong/domain/content/RoomContentRepositoryTest.java index bd15ed56..caffa0dd 100644 --- a/backend/src/test/java/ddangkong/domain/question/RoomQuestionRepositoryTest.java +++ b/backend/src/test/java/ddangkong/domain/content/RoomContentRepositoryTest.java @@ -1,9 +1,9 @@ -package ddangkong.domain.question; +package ddangkong.domain.content; import static org.assertj.core.api.Assertions.assertThat; import ddangkong.domain.BaseRepositoryTest; -import ddangkong.domain.room.RoomQuestion; +import ddangkong.domain.room.RoomContent; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -11,14 +11,14 @@ class RoomQuestionRepositoryTest extends BaseRepositoryTest { @Autowired - private RoomQuestionRepository roomQuestionRepository; + private RoomContentRepository roomContentRepository; @Nested class 방의_최신_질문_조회 { @Test void 방의_가장_최신의_질문을_조회할_수_있다() { - RoomQuestion actual = roomQuestionRepository.findTopByRoomIdOrderByCreatedAtDesc(1L).get(); + RoomContent actual = roomContentRepository.findTopByRoomIdOrderByCreatedAtDesc(1L).get(); assertThat(actual.getId()).isEqualTo(2L); } diff --git a/backend/src/test/java/ddangkong/service/question/BalanceQuestionServiceTest.java b/backend/src/test/java/ddangkong/service/content/BalanceContentServiceTest.java similarity index 56% rename from backend/src/test/java/ddangkong/service/question/BalanceQuestionServiceTest.java rename to backend/src/test/java/ddangkong/service/content/BalanceContentServiceTest.java index 3b30e230..f398f3fd 100644 --- a/backend/src/test/java/ddangkong/service/question/BalanceQuestionServiceTest.java +++ b/backend/src/test/java/ddangkong/service/content/BalanceContentServiceTest.java @@ -1,42 +1,42 @@ -package ddangkong.service.question; +package ddangkong.service.content; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import ddangkong.controller.option.dto.BalanceOptionResponse; -import ddangkong.controller.question.dto.BalanceQuestionResponse; -import ddangkong.domain.question.Category; +import ddangkong.controller.content.dto.BalanceContentResponse; +import ddangkong.domain.content.Category; import ddangkong.service.BaseServiceTest; import ddangkong.service.excpetion.BusinessLogicException; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -class BalanceQuestionServiceTest extends BaseServiceTest { +class BalanceContentServiceTest extends BaseServiceTest { private static final Long PROGRESS_ROOM_ID = 1L; private static final Long NOT_EXIST_ROOM_ID = 2L; - private static final BalanceQuestionResponse BALANCE_QUESTION_RESPONSE = new BalanceQuestionResponse( + private static final BalanceContentResponse BALANCE_CONTENT_RESPONSE = new BalanceContentResponse( 1L, Category.EXAMPLE, "민초 vs 반민초", new BalanceOptionResponse(1L, "민초"), new BalanceOptionResponse(2L, "반민초")); @Autowired - private BalanceQuestionService balanceQuestionService; + private BalanceContentService balanceContentService; @Nested - class 방의_최신_질문_조회 { + class 방의_최신_내용_조회 { @Test - void 방의_최신_질문을_조회할_수_있다() { - BalanceQuestionResponse actual = balanceQuestionService.findRecentBalanceQuestion(PROGRESS_ROOM_ID); + void 방의_최신_내용을_조회할_수_있다() { + BalanceContentResponse actual = balanceContentService.findRecentBalanceContent(PROGRESS_ROOM_ID); - assertThat(actual).isEqualTo(BALANCE_QUESTION_RESPONSE); + assertThat(actual).isEqualTo(BALANCE_CONTENT_RESPONSE); } @Test void 방이_없을_경우_예외를_던진다() { - assertThatThrownBy(() -> balanceQuestionService.findRecentBalanceQuestion(NOT_EXIST_ROOM_ID)) + assertThatThrownBy(() -> balanceContentService.findRecentBalanceContent(NOT_EXIST_ROOM_ID)) .isInstanceOf(BusinessLogicException.class) .hasMessage("해당 방의 질문이 존재하지 않습니다."); } diff --git a/backend/src/test/resources/init-test.sql b/backend/src/test/resources/init-test.sql index 71dbf94a..90b21797 100644 --- a/backend/src/test/resources/init-test.sql +++ b/backend/src/test/resources/init-test.sql @@ -2,30 +2,30 @@ SET REFERENTIAL_INTEGRITY FALSE; TRUNCATE TABLE member; TRUNCATE TABLE balance_option; -TRUNCATE TABLE balance_question; +TRUNCATE TABLE balance_content; TRUNCATE TABLE balance_vote; TRUNCATE TABLE room; -TRUNCATE TABLE room_question; +TRUNCATE TABLE room_content; ALTER TABLE member ALTER COLUMN ID RESTART WITH 1; ALTER TABLE balance_option ALTER COLUMN ID RESTART WITH 1; -ALTER TABLE balance_question ALTER COLUMN ID RESTART WITH 1; +ALTER TABLE balance_content ALTER COLUMN ID RESTART WITH 1; ALTER TABLE balance_vote ALTER COLUMN ID RESTART WITH 1; ALTER TABLE room ALTER COLUMN ID RESTART WITH 1; -ALTER TABLE room_question ALTER COLUMN ID RESTART WITH 1; +ALTER TABLE room_content ALTER COLUMN ID RESTART WITH 1; INSERT INTO room() VALUES (); INSERT INTO member(nickname, room_id) -VALUES ('mohamedeu al katan', 1), ('deundeun ', 1), ('rupi', 1), ('rapper lee', 1); +VALUES ('mohamedeu al katan', 1), ('deundeun', 1), ('rupi', 1), ('rapper lee', 1); -INSERT INTO room_question(room_id, balance_question_id, created_at) +INSERT INTO room_content(room_id, balance_content_id, created_at) VALUES (1, 2, '2024-07-18 19:50:00.000'), (1, 1, '2024-07-18 20:00:00.000'); -INSERT INTO balance_question(category, content) +INSERT INTO balance_content(category, name) VALUES ('EXAMPLE', '민초 vs 반민초'), ('EXAMPLE', '월 200 백수 vs 월 500 직장인'); -INSERT INTO balance_option(content, balance_question_id) +INSERT INTO balance_option(name, balance_content_id) VALUES ('민초', 1), ('반민초', 1), ('월 200 백수', 2), ('월 200 직장인', 2); INSERT INTO balance_vote(balance_option_id, member_id) From 8247b61f59fd215e00594bdc205ce3359b10fbff Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Mon, 22 Jul 2024 13:10:46 +0900 Subject: [PATCH 0133/1013] =?UTF-8?q?fix:=20RoomContentRepository=EB=A5=BC?= =?UTF-8?q?=20room=20=ED=8C=A8=ED=82=A4=EC=A7=80=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/{content => room}/RoomContentRepository.java | 2 +- .../ddangkong/service/content/BalanceContentService.java | 2 +- .../domain/{content => room}/RoomContentRepositoryTest.java | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) rename backend/src/main/java/ddangkong/domain/{content => room}/RoomContentRepository.java (89%) rename backend/src/test/java/ddangkong/domain/{content => room}/RoomContentRepositoryTest.java (81%) diff --git a/backend/src/main/java/ddangkong/domain/content/RoomContentRepository.java b/backend/src/main/java/ddangkong/domain/room/RoomContentRepository.java similarity index 89% rename from backend/src/main/java/ddangkong/domain/content/RoomContentRepository.java rename to backend/src/main/java/ddangkong/domain/room/RoomContentRepository.java index bd20d71c..7f5c967b 100644 --- a/backend/src/main/java/ddangkong/domain/content/RoomContentRepository.java +++ b/backend/src/main/java/ddangkong/domain/room/RoomContentRepository.java @@ -1,4 +1,4 @@ -package ddangkong.domain.content; +package ddangkong.domain.room; import ddangkong.domain.room.RoomContent; import java.util.Optional; diff --git a/backend/src/main/java/ddangkong/service/content/BalanceContentService.java b/backend/src/main/java/ddangkong/service/content/BalanceContentService.java index a87ae3a4..90fec0e1 100644 --- a/backend/src/main/java/ddangkong/service/content/BalanceContentService.java +++ b/backend/src/main/java/ddangkong/service/content/BalanceContentService.java @@ -4,7 +4,7 @@ import ddangkong.domain.option.BalanceOption; import ddangkong.domain.option.BalanceOptionRepository; import ddangkong.domain.content.BalanceContent; -import ddangkong.domain.content.RoomContentRepository; +import ddangkong.domain.room.RoomContentRepository; import ddangkong.service.excpetion.BusinessLogicException; import ddangkong.service.excpetion.ViolateDataException; import java.util.List; diff --git a/backend/src/test/java/ddangkong/domain/content/RoomContentRepositoryTest.java b/backend/src/test/java/ddangkong/domain/room/RoomContentRepositoryTest.java similarity index 81% rename from backend/src/test/java/ddangkong/domain/content/RoomContentRepositoryTest.java rename to backend/src/test/java/ddangkong/domain/room/RoomContentRepositoryTest.java index caffa0dd..a03a157a 100644 --- a/backend/src/test/java/ddangkong/domain/content/RoomContentRepositoryTest.java +++ b/backend/src/test/java/ddangkong/domain/room/RoomContentRepositoryTest.java @@ -1,14 +1,13 @@ -package ddangkong.domain.content; +package ddangkong.domain.room; import static org.assertj.core.api.Assertions.assertThat; import ddangkong.domain.BaseRepositoryTest; -import ddangkong.domain.room.RoomContent; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -class RoomQuestionRepositoryTest extends BaseRepositoryTest { +class RoomContentRepositoryTest extends BaseRepositoryTest { @Autowired private RoomContentRepository roomContentRepository; From 30bb5953f4a9348129a0f05a03481a11b3c0326e Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Mon, 22 Jul 2024 17:20:33 +0900 Subject: [PATCH 0134/1013] =?UTF-8?q?fix:=20=EC=84=9C=EB=B2=84=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EC=8B=9C,=20=EC=97=90=EB=9F=AC=20=EC=8A=A4?= =?UTF-8?q?=ED=83=9D=20=ED=8A=B8=EB=A0=88=EC=9D=B4=EC=8A=A4=EA=B9=8C?= =?UTF-8?q?=EC=A7=80=20=EC=B6=9C=EB=A0=A5=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD,=20=EC=9D=BC=EB=B6=80=20`@ResponseStatus`=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/exception/GlobalExceptionHandler.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java b/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java index 27def5ca..1814c07e 100644 --- a/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java +++ b/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java @@ -17,6 +17,7 @@ public class GlobalExceptionHandler { private static final String SERVER_ERROR_MESSAGE = "서버 오류가 발생했습니다. 관리자에게 문의하세요."; @ExceptionHandler + @ResponseStatus(HttpStatus.BAD_REQUEST) public ErrorResponse handleBindingException(BindException e) { log.warn(e.getMessage()); @@ -24,6 +25,7 @@ public ErrorResponse handleBindingException(BindException e) { } @ExceptionHandler + @ResponseStatus(HttpStatus.BAD_REQUEST) public ErrorResponse handleConstraintViolationException(ConstraintViolationException e) { log.warn(e.getMessage()); @@ -41,7 +43,7 @@ public ErrorResponse handleBusinessLogicException(BusinessLogicException e) { @ExceptionHandler @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public ErrorResponse handleViolateDataException(ViolateDataException e) { - log.error(e.getMessage()); + log.error(e.getMessage(), e); return new ErrorResponse(SERVER_ERROR_MESSAGE); } @@ -49,7 +51,7 @@ public ErrorResponse handleViolateDataException(ViolateDataException e) { @ExceptionHandler @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public ErrorResponse handleException(Exception e) { - log.error(e.getMessage()); + log.error(e.getMessage(), e); return new ErrorResponse(SERVER_ERROR_MESSAGE); } From a81910f096341abc9b9116ecb8c1be750411319d Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Mon, 22 Jul 2024 17:27:44 +0900 Subject: [PATCH 0135/1013] =?UTF-8?q?refactor:=20balance=20=ED=8C=A8?= =?UTF-8?q?=ED=82=A4=EC=A7=80=20=EC=B6=94=EA=B0=80=20#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/BalanceContentController.java | 6 +++--- .../content/dto/BalanceContentResponse.java | 10 +++++----- .../option/dto/BalanceOptionResponse.java | 4 ++-- .../domain/{ => balance}/content/BalanceContent.java | 2 +- .../domain/{ => balance}/content/Category.java | 2 +- .../domain/{room => balance/content}/Room.java | 2 +- .../{room => balance/content}/RoomContent.java | 3 +-- .../content}/RoomContentRepository.java | 3 +-- .../domain/{ => balance}/option/BalanceOption.java | 4 ++-- .../option/BalanceOptionRepository.java | 4 ++-- .../domain/{ => balance}/vote/BalanceVote.java | 4 ++-- .../main/java/ddangkong/domain/member/Member.java | 2 +- .../{ => balance}/content/BalanceContentService.java | 12 ++++++------ .../content/BalanceContentControllerTest.java | 8 ++++---- .../content}/RoomContentRepositoryTest.java | 2 +- .../content/BalanceContentServiceTest.java | 8 ++++---- 16 files changed, 37 insertions(+), 39 deletions(-) rename backend/src/main/java/ddangkong/controller/{ => balance}/content/BalanceContentController.java (78%) rename backend/src/main/java/ddangkong/controller/{ => balance}/content/dto/BalanceContentResponse.java (70%) rename backend/src/main/java/ddangkong/controller/{ => balance}/option/dto/BalanceOptionResponse.java (71%) rename backend/src/main/java/ddangkong/domain/{ => balance}/content/BalanceContent.java (94%) rename backend/src/main/java/ddangkong/domain/{ => balance}/content/Category.java (51%) rename backend/src/main/java/ddangkong/domain/{room => balance/content}/Room.java (90%) rename backend/src/main/java/ddangkong/domain/{room => balance/content}/RoomContent.java (91%) rename backend/src/main/java/ddangkong/domain/{room => balance/content}/RoomContentRepository.java (77%) rename backend/src/main/java/ddangkong/domain/{ => balance}/option/BalanceOption.java (89%) rename backend/src/main/java/ddangkong/domain/{ => balance}/option/BalanceOptionRepository.java (72%) rename backend/src/main/java/ddangkong/domain/{ => balance}/vote/BalanceVote.java (90%) rename backend/src/main/java/ddangkong/service/{ => balance}/content/BalanceContentService.java (84%) rename backend/src/test/java/ddangkong/controller/{ => balance}/content/BalanceContentControllerTest.java (81%) rename backend/src/test/java/ddangkong/domain/{room => balance/content}/RoomContentRepositoryTest.java (94%) rename backend/src/test/java/ddangkong/service/{ => balance}/content/BalanceContentServiceTest.java (86%) diff --git a/backend/src/main/java/ddangkong/controller/content/BalanceContentController.java b/backend/src/main/java/ddangkong/controller/balance/content/BalanceContentController.java similarity index 78% rename from backend/src/main/java/ddangkong/controller/content/BalanceContentController.java rename to backend/src/main/java/ddangkong/controller/balance/content/BalanceContentController.java index 495d6752..6bfaed6b 100644 --- a/backend/src/main/java/ddangkong/controller/content/BalanceContentController.java +++ b/backend/src/main/java/ddangkong/controller/balance/content/BalanceContentController.java @@ -1,7 +1,7 @@ -package ddangkong.controller.content; +package ddangkong.controller.balance.content; -import ddangkong.controller.content.dto.BalanceContentResponse; -import ddangkong.service.content.BalanceContentService; +import ddangkong.controller.balance.content.dto.BalanceContentResponse; +import ddangkong.service.balance.content.BalanceContentService; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; diff --git a/backend/src/main/java/ddangkong/controller/content/dto/BalanceContentResponse.java b/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentResponse.java similarity index 70% rename from backend/src/main/java/ddangkong/controller/content/dto/BalanceContentResponse.java rename to backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentResponse.java index 74c26770..c27445f9 100644 --- a/backend/src/main/java/ddangkong/controller/content/dto/BalanceContentResponse.java +++ b/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentResponse.java @@ -1,9 +1,9 @@ -package ddangkong.controller.content.dto; +package ddangkong.controller.balance.content.dto; -import ddangkong.controller.option.dto.BalanceOptionResponse; -import ddangkong.domain.content.BalanceContent; -import ddangkong.domain.content.Category; -import ddangkong.domain.option.BalanceOption; +import ddangkong.controller.balance.option.dto.BalanceOptionResponse; +import ddangkong.domain.balance.content.BalanceContent; +import ddangkong.domain.balance.content.Category; +import ddangkong.domain.balance.option.BalanceOption; import lombok.Builder; public record BalanceContentResponse( diff --git a/backend/src/main/java/ddangkong/controller/option/dto/BalanceOptionResponse.java b/backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionResponse.java similarity index 71% rename from backend/src/main/java/ddangkong/controller/option/dto/BalanceOptionResponse.java rename to backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionResponse.java index 665562cd..0005c15d 100644 --- a/backend/src/main/java/ddangkong/controller/option/dto/BalanceOptionResponse.java +++ b/backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionResponse.java @@ -1,6 +1,6 @@ -package ddangkong.controller.option.dto; +package ddangkong.controller.balance.option.dto; -import ddangkong.domain.option.BalanceOption; +import ddangkong.domain.balance.option.BalanceOption; public record BalanceOptionResponse( Long optionId, diff --git a/backend/src/main/java/ddangkong/domain/content/BalanceContent.java b/backend/src/main/java/ddangkong/domain/balance/content/BalanceContent.java similarity index 94% rename from backend/src/main/java/ddangkong/domain/content/BalanceContent.java rename to backend/src/main/java/ddangkong/domain/balance/content/BalanceContent.java index bb223821..5fb9026c 100644 --- a/backend/src/main/java/ddangkong/domain/content/BalanceContent.java +++ b/backend/src/main/java/ddangkong/domain/balance/content/BalanceContent.java @@ -1,4 +1,4 @@ -package ddangkong.domain.content; +package ddangkong.domain.balance.content; import jakarta.persistence.Column; import jakarta.persistence.Entity; diff --git a/backend/src/main/java/ddangkong/domain/content/Category.java b/backend/src/main/java/ddangkong/domain/balance/content/Category.java similarity index 51% rename from backend/src/main/java/ddangkong/domain/content/Category.java rename to backend/src/main/java/ddangkong/domain/balance/content/Category.java index ba69a0a0..07a510c2 100644 --- a/backend/src/main/java/ddangkong/domain/content/Category.java +++ b/backend/src/main/java/ddangkong/domain/balance/content/Category.java @@ -1,4 +1,4 @@ -package ddangkong.domain.content; +package ddangkong.domain.balance.content; public enum Category { EXAMPLE, diff --git a/backend/src/main/java/ddangkong/domain/room/Room.java b/backend/src/main/java/ddangkong/domain/balance/content/Room.java similarity index 90% rename from backend/src/main/java/ddangkong/domain/room/Room.java rename to backend/src/main/java/ddangkong/domain/balance/content/Room.java index 9f8b1bd0..7dd029e8 100644 --- a/backend/src/main/java/ddangkong/domain/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/content/Room.java @@ -1,4 +1,4 @@ -package ddangkong.domain.room; +package ddangkong.domain.balance.content; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; diff --git a/backend/src/main/java/ddangkong/domain/room/RoomContent.java b/backend/src/main/java/ddangkong/domain/balance/content/RoomContent.java similarity index 91% rename from backend/src/main/java/ddangkong/domain/room/RoomContent.java rename to backend/src/main/java/ddangkong/domain/balance/content/RoomContent.java index b9508e77..3f99b1f8 100644 --- a/backend/src/main/java/ddangkong/domain/room/RoomContent.java +++ b/backend/src/main/java/ddangkong/domain/balance/content/RoomContent.java @@ -1,7 +1,6 @@ -package ddangkong.domain.room; +package ddangkong.domain.balance.content; import ddangkong.domain.BaseEntity; -import ddangkong.domain.content.BalanceContent; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; diff --git a/backend/src/main/java/ddangkong/domain/room/RoomContentRepository.java b/backend/src/main/java/ddangkong/domain/balance/content/RoomContentRepository.java similarity index 77% rename from backend/src/main/java/ddangkong/domain/room/RoomContentRepository.java rename to backend/src/main/java/ddangkong/domain/balance/content/RoomContentRepository.java index 7f5c967b..ea9f4ce2 100644 --- a/backend/src/main/java/ddangkong/domain/room/RoomContentRepository.java +++ b/backend/src/main/java/ddangkong/domain/balance/content/RoomContentRepository.java @@ -1,6 +1,5 @@ -package ddangkong.domain.room; +package ddangkong.domain.balance.content; -import ddangkong.domain.room.RoomContent; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/backend/src/main/java/ddangkong/domain/option/BalanceOption.java b/backend/src/main/java/ddangkong/domain/balance/option/BalanceOption.java similarity index 89% rename from backend/src/main/java/ddangkong/domain/option/BalanceOption.java rename to backend/src/main/java/ddangkong/domain/balance/option/BalanceOption.java index 894e22e6..bc65918d 100644 --- a/backend/src/main/java/ddangkong/domain/option/BalanceOption.java +++ b/backend/src/main/java/ddangkong/domain/balance/option/BalanceOption.java @@ -1,6 +1,6 @@ -package ddangkong.domain.option; +package ddangkong.domain.balance.option; -import ddangkong.domain.content.BalanceContent; +import ddangkong.domain.balance.content.BalanceContent; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/backend/src/main/java/ddangkong/domain/option/BalanceOptionRepository.java b/backend/src/main/java/ddangkong/domain/balance/option/BalanceOptionRepository.java similarity index 72% rename from backend/src/main/java/ddangkong/domain/option/BalanceOptionRepository.java rename to backend/src/main/java/ddangkong/domain/balance/option/BalanceOptionRepository.java index 7635ab60..10d886be 100644 --- a/backend/src/main/java/ddangkong/domain/option/BalanceOptionRepository.java +++ b/backend/src/main/java/ddangkong/domain/balance/option/BalanceOptionRepository.java @@ -1,6 +1,6 @@ -package ddangkong.domain.option; +package ddangkong.domain.balance.option; -import ddangkong.domain.content.BalanceContent; +import ddangkong.domain.balance.content.BalanceContent; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/backend/src/main/java/ddangkong/domain/vote/BalanceVote.java b/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVote.java similarity index 90% rename from backend/src/main/java/ddangkong/domain/vote/BalanceVote.java rename to backend/src/main/java/ddangkong/domain/balance/vote/BalanceVote.java index ec09a2a4..981d3715 100644 --- a/backend/src/main/java/ddangkong/domain/vote/BalanceVote.java +++ b/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVote.java @@ -1,7 +1,7 @@ -package ddangkong.domain.vote; +package ddangkong.domain.balance.vote; +import ddangkong.domain.balance.option.BalanceOption; import ddangkong.domain.member.Member; -import ddangkong.domain.option.BalanceOption; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; diff --git a/backend/src/main/java/ddangkong/domain/member/Member.java b/backend/src/main/java/ddangkong/domain/member/Member.java index 9d4e59c5..efedc670 100644 --- a/backend/src/main/java/ddangkong/domain/member/Member.java +++ b/backend/src/main/java/ddangkong/domain/member/Member.java @@ -1,6 +1,6 @@ package ddangkong.domain.member; -import ddangkong.domain.room.Room; +import ddangkong.domain.balance.content.Room; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/backend/src/main/java/ddangkong/service/content/BalanceContentService.java b/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java similarity index 84% rename from backend/src/main/java/ddangkong/service/content/BalanceContentService.java rename to backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java index 90fec0e1..a3a4b611 100644 --- a/backend/src/main/java/ddangkong/service/content/BalanceContentService.java +++ b/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java @@ -1,10 +1,10 @@ -package ddangkong.service.content; +package ddangkong.service.balance.content; -import ddangkong.controller.content.dto.BalanceContentResponse; -import ddangkong.domain.option.BalanceOption; -import ddangkong.domain.option.BalanceOptionRepository; -import ddangkong.domain.content.BalanceContent; -import ddangkong.domain.room.RoomContentRepository; +import ddangkong.controller.balance.content.dto.BalanceContentResponse; +import ddangkong.domain.balance.content.BalanceContent; +import ddangkong.domain.balance.content.RoomContentRepository; +import ddangkong.domain.balance.option.BalanceOption; +import ddangkong.domain.balance.option.BalanceOptionRepository; import ddangkong.service.excpetion.BusinessLogicException; import ddangkong.service.excpetion.ViolateDataException; import java.util.List; diff --git a/backend/src/test/java/ddangkong/controller/content/BalanceContentControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java similarity index 81% rename from backend/src/test/java/ddangkong/controller/content/BalanceContentControllerTest.java rename to backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java index 99107635..b38df8c0 100644 --- a/backend/src/test/java/ddangkong/controller/content/BalanceContentControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java @@ -1,11 +1,11 @@ -package ddangkong.controller.content; +package ddangkong.controller.balance.content; import static org.assertj.core.api.Assertions.assertThat; import ddangkong.controller.BaseControllerTest; -import ddangkong.controller.option.dto.BalanceOptionResponse; -import ddangkong.controller.content.dto.BalanceContentResponse; -import ddangkong.domain.content.Category; +import ddangkong.controller.balance.content.dto.BalanceContentResponse; +import ddangkong.controller.balance.option.dto.BalanceOptionResponse; +import ddangkong.domain.balance.content.Category; import io.restassured.RestAssured; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; diff --git a/backend/src/test/java/ddangkong/domain/room/RoomContentRepositoryTest.java b/backend/src/test/java/ddangkong/domain/balance/content/RoomContentRepositoryTest.java similarity index 94% rename from backend/src/test/java/ddangkong/domain/room/RoomContentRepositoryTest.java rename to backend/src/test/java/ddangkong/domain/balance/content/RoomContentRepositoryTest.java index a03a157a..fc940a0d 100644 --- a/backend/src/test/java/ddangkong/domain/room/RoomContentRepositoryTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/content/RoomContentRepositoryTest.java @@ -1,4 +1,4 @@ -package ddangkong.domain.room; +package ddangkong.domain.balance.content; import static org.assertj.core.api.Assertions.assertThat; diff --git a/backend/src/test/java/ddangkong/service/content/BalanceContentServiceTest.java b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java similarity index 86% rename from backend/src/test/java/ddangkong/service/content/BalanceContentServiceTest.java rename to backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java index f398f3fd..d673cab3 100644 --- a/backend/src/test/java/ddangkong/service/content/BalanceContentServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java @@ -1,11 +1,11 @@ -package ddangkong.service.content; +package ddangkong.service.balance.content; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import ddangkong.controller.option.dto.BalanceOptionResponse; -import ddangkong.controller.content.dto.BalanceContentResponse; -import ddangkong.domain.content.Category; +import ddangkong.controller.balance.content.dto.BalanceContentResponse; +import ddangkong.controller.balance.option.dto.BalanceOptionResponse; +import ddangkong.domain.balance.content.Category; import ddangkong.service.BaseServiceTest; import ddangkong.service.excpetion.BusinessLogicException; import org.junit.jupiter.api.Nested; From f5467fc2c35b0e3492db4063e11041021f73445a Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Mon, 22 Jul 2024 17:33:02 +0900 Subject: [PATCH 0136/1013] =?UTF-8?q?fix:=20API=20=EB=AA=85=EC=84=B8?= =?UTF-8?q?=EC=84=9C=EB=A5=BC=20=EB=B0=98=EC=98=81=ED=95=98=EC=97=AC=20Res?= =?UTF-8?q?ponse=20=EC=88=98=EC=A0=95=20#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../balance/content/dto/BalanceContentResponse.java | 4 ++-- .../controller/balance/option/dto/BalanceOptionResponse.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentResponse.java b/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentResponse.java index c27445f9..66543da9 100644 --- a/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentResponse.java +++ b/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentResponse.java @@ -7,9 +7,9 @@ import lombok.Builder; public record BalanceContentResponse( - Long questionId, + Long contentId, Category category, - String title, + String question, BalanceOptionResponse firstOption, BalanceOptionResponse secondOption ) { diff --git a/backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionResponse.java b/backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionResponse.java index 0005c15d..a2c0f788 100644 --- a/backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionResponse.java +++ b/backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionResponse.java @@ -4,7 +4,7 @@ public record BalanceOptionResponse( Long optionId, - String content + String name ) { public static BalanceOptionResponse from(BalanceOption balanceOption) { return new BalanceOptionResponse(balanceOption.getId(), balanceOption.getName()); From daef26e28e9c33380acc4947e3151937d8034e77 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Mon, 22 Jul 2024 17:47:26 +0900 Subject: [PATCH 0137/1013] =?UTF-8?q?feat:=20BalanceContentController=20ro?= =?UTF-8?q?omId=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20=EA=B2=80=EC=82=AC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../balance/content/BalanceContentController.java | 5 ++++- .../balance/content/BalanceContentControllerTest.java | 8 ++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/ddangkong/controller/balance/content/BalanceContentController.java b/backend/src/main/java/ddangkong/controller/balance/content/BalanceContentController.java index 6bfaed6b..2a040f5a 100644 --- a/backend/src/main/java/ddangkong/controller/balance/content/BalanceContentController.java +++ b/backend/src/main/java/ddangkong/controller/balance/content/BalanceContentController.java @@ -2,7 +2,9 @@ import ddangkong.controller.balance.content.dto.BalanceContentResponse; import ddangkong.service.balance.content.BalanceContentService; +import jakarta.validation.constraints.Positive; import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; @@ -10,13 +12,14 @@ @RestController @RequestMapping("/api") +@Validated @RequiredArgsConstructor public class BalanceContentController { private final BalanceContentService balanceContentService; @GetMapping("/balances/rooms/{roomId}/question") - public BalanceContentResponse getBalanceContent(@PathVariable Long roomId) { + public BalanceContentResponse getBalanceContent(@PathVariable @Positive Long roomId) { return balanceContentService.findRecentBalanceContent(roomId); } } diff --git a/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java index b38df8c0..b7a6fdc7 100644 --- a/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java @@ -30,5 +30,13 @@ class 방의_질문_조회 { assertThat(actual).isEqualTo(EXPECTED_RESPONSE); } + + @Test + void 방의_식별자가_음수인_경우_예외를_던진다() { + RestAssured.given().log().all() + .when().get("/api/balances/rooms/-1/question") + .then().log().all() + .statusCode(400); + } } } From 854cd734ac3c1e3e74584798a638d07ee41197af Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Mon, 22 Jul 2024 17:48:36 +0900 Subject: [PATCH 0138/1013] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EB=A5=BC=20=EB=AA=85=ED=99=95=ED=95=98=EA=B2=8C=20=EC=84=A4?= =?UTF-8?q?=EB=AA=85=ED=95=98=EA=B8=B0=20=EC=9C=84=ED=95=B4,=20Nested=20cl?= =?UTF-8?q?ass=20=EC=9D=B4=EB=A6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../balance/content/BalanceContentControllerTest.java | 2 +- .../service/balance/content/BalanceContentServiceTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java index b7a6fdc7..16fe63bb 100644 --- a/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java @@ -18,7 +18,7 @@ class BalanceContentControllerTest extends BaseControllerTest { new BalanceOptionResponse(2L, "반민초")); @Nested - class 방의_질문_조회 { + class 현재_방의_내용_조회 { @Test void 현재_방의_질문을_조회할_수_있다() { diff --git a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java index d673cab3..ec13bc3b 100644 --- a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java @@ -25,7 +25,7 @@ class BalanceContentServiceTest extends BaseServiceTest { private BalanceContentService balanceContentService; @Nested - class 방의_최신_내용_조회 { + class 현재_방의_내용_조회 { @Test void 방의_최신_내용을_조회할_수_있다() { From ed13e2533a43a711b5be6e39ec062518ac3e8e6e Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Mon, 22 Jul 2024 17:53:24 +0900 Subject: [PATCH 0139/1013] =?UTF-8?q?test:=20given,=20when,=20then=20?= =?UTF-8?q?=EC=A3=BC=EC=84=9D=20=EC=B6=94=EA=B0=80=20#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/BalanceContentControllerTest.java | 13 ++++++++----- .../balance/content/RoomContentRepositoryTest.java | 7 ++++++- .../balance/content/BalanceContentServiceTest.java | 3 +++ 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java index 16fe63bb..67d24b7d 100644 --- a/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java @@ -12,27 +12,30 @@ class BalanceContentControllerTest extends BaseControllerTest { - private static final BalanceContentResponse EXPECTED_RESPONSE = new BalanceContentResponse( - 1L, Category.EXAMPLE, "민초 vs 반민초", - new BalanceOptionResponse(1L, "민초"), - new BalanceOptionResponse(2L, "반민초")); - @Nested class 현재_방의_내용_조회 { + private static final BalanceContentResponse EXPECTED_RESPONSE = new BalanceContentResponse( + 1L, Category.EXAMPLE, "민초 vs 반민초", + new BalanceOptionResponse(1L, "민초"), + new BalanceOptionResponse(2L, "반민초")); + @Test void 현재_방의_질문을_조회할_수_있다() { + // when BalanceContentResponse actual = RestAssured.given().log().all() .when().get("/api/balances/rooms/1/question") .then().log().all() .statusCode(200) .extract().as(BalanceContentResponse.class); + // then assertThat(actual).isEqualTo(EXPECTED_RESPONSE); } @Test void 방의_식별자가_음수인_경우_예외를_던진다() { + // when & then RestAssured.given().log().all() .when().get("/api/balances/rooms/-1/question") .then().log().all() diff --git a/backend/src/test/java/ddangkong/domain/balance/content/RoomContentRepositoryTest.java b/backend/src/test/java/ddangkong/domain/balance/content/RoomContentRepositoryTest.java index fc940a0d..67af2b4e 100644 --- a/backend/src/test/java/ddangkong/domain/balance/content/RoomContentRepositoryTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/content/RoomContentRepositoryTest.java @@ -17,8 +17,13 @@ class 방의_최신_질문_조회 { @Test void 방의_가장_최신의_질문을_조회할_수_있다() { - RoomContent actual = roomContentRepository.findTopByRoomIdOrderByCreatedAtDesc(1L).get(); + // given + Long recentContentId = 1L; + // when + RoomContent actual = roomContentRepository.findTopByRoomIdOrderByCreatedAtDesc(recentContentId).get(); + + // then assertThat(actual.getId()).isEqualTo(2L); } } diff --git a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java index ec13bc3b..9831c766 100644 --- a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java @@ -29,13 +29,16 @@ class 현재_방의_내용_조회 { @Test void 방의_최신_내용을_조회할_수_있다() { + // when BalanceContentResponse actual = balanceContentService.findRecentBalanceContent(PROGRESS_ROOM_ID); + // then assertThat(actual).isEqualTo(BALANCE_CONTENT_RESPONSE); } @Test void 방이_없을_경우_예외를_던진다() { + // when & then assertThatThrownBy(() -> balanceContentService.findRecentBalanceContent(NOT_EXIST_ROOM_ID)) .isInstanceOf(BusinessLogicException.class) .hasMessage("해당 방의 질문이 존재하지 않습니다."); From 3041d4a68691842f844e82a261d81f6216fc9327 Mon Sep 17 00:00:00 2001 From: leegwichan Date: Mon, 22 Jul 2024 23:30:54 +0900 Subject: [PATCH 0140/1013] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EB=B3=80=EA=B2=BD=20#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 테스트가 어떤 도메인인지 드러나도록 변경 --- .../service/balance/content/BalanceContentServiceTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java index 9831c766..fc87fda2 100644 --- a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java @@ -25,10 +25,10 @@ class BalanceContentServiceTest extends BaseServiceTest { private BalanceContentService balanceContentService; @Nested - class 현재_방의_내용_조회 { + class 현재_방의_밸런스_게임_내용_조회 { @Test - void 방의_최신_내용을_조회할_수_있다() { + void 방의_최신_밸런스_게임_내용을_조회할_수_있다() { // when BalanceContentResponse actual = balanceContentService.findRecentBalanceContent(PROGRESS_ROOM_ID); From 5503fbf613a074d40b778e6763dd120ad36f0740 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 17:16:16 +0900 Subject: [PATCH 0141/1013] =?UTF-8?q?feat:=20EC2=EC=97=90=EC=84=9C=20Docke?= =?UTF-8?q?r=20Image=20pull=20=ED=95=98=EB=8A=94=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=EA=B9=8C=EC=A7=80=20=EA=B5=AC=ED=98=84=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 36 +++++++++++++++++++++++++++++++-- backend/Dockerfile | 11 ++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 backend/Dockerfile diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 2c1337df..0621405b 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -12,8 +12,40 @@ permissions: contents: read jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Build with Gradle + run: ./gradlew clean bootJar + + - name: Log in to Docker Hub + uses: docker/login-action@v4 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build Docker image + run: docker build ./Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/ddangkong-api-dev:latest + + - name: Push Docker image + run: docker push ${{ secrets.DOCKER_USERNAME }}/ddangkong-api-dev:latest + + deploy: runs-on: [self-hosted, linux, ARM64] # Self hosted runner 사용 steps: - - name: Execute script on EC2 to deploy - run: sudo sh ~/deploy-script-dev.sh + - name: Pull docker image + run: docker pull ${{ secrets.DOCKER_USERNAME }}/ddangkong-api-dev:latest \ No newline at end of file diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 00000000..ddec20a8 --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,11 @@ +# Use an official OpenJDK runtime as a parent image +FROM openjdk:17-jre-slim + +# Copy the jar file into the container +COPY build/libs/*.jar app.jar + +# Make port 8080 available to the world outside this container +EXPOSE 8080 + +# Run the jar file +ENTRYPOINT ["nohup", "java", "-jar", "-Duser.timezone=Asia/Seoul","-Dspring.profiles.active=dev", "app.jar", "&"] From 324031be3ea899f08806fb088bbf9edbe4c24a7d Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 17:19:30 +0900 Subject: [PATCH 0142/1013] =?UTF-8?q?fix:=20build=20job=20=EC=9D=B4?= =?UTF-8?q?=ED=9B=84=20deploy=20job=EC=9D=B4=20=EC=88=98=ED=96=89=EB=90=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 0621405b..779c62ed 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -45,6 +45,7 @@ jobs: deploy: + needs: build runs-on: [self-hosted, linux, ARM64] # Self hosted runner 사용 steps: - name: Pull docker image From f18030aedb31ac0b36147101f7b9cc1c45f06201 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 17:20:08 +0900 Subject: [PATCH 0143/1013] =?UTF-8?q?fix:=20docker/login-action=20?= =?UTF-8?q?=EB=B2=84=EC=A0=84=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 779c62ed..bf9b07f4 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -32,7 +32,7 @@ jobs: run: ./gradlew clean bootJar - name: Log in to Docker Hub - uses: docker/login-action@v4 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} From fa662e03140e50d5a1ef9977a133ee201f595abc Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 17:20:41 +0900 Subject: [PATCH 0144/1013] =?UTF-8?q?fix:=20ec2=20docker=20=EB=AA=85?= =?UTF-8?q?=EB=A0=B9=EC=96=B4=20sudo=20=EA=B6=8C=ED=95=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index bf9b07f4..dc9f2604 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -49,4 +49,4 @@ jobs: runs-on: [self-hosted, linux, ARM64] # Self hosted runner 사용 steps: - name: Pull docker image - run: docker pull ${{ secrets.DOCKER_USERNAME }}/ddangkong-api-dev:latest \ No newline at end of file + run: sudo docker pull ${{ secrets.DOCKER_USERNAME }}/ddangkong-api-dev:latest \ No newline at end of file From 96830b3289bbca90e877746d6605732d0e6bf9de Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 17:22:06 +0900 Subject: [PATCH 0145/1013] =?UTF-8?q?fix:=20work-directory=20backend=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=EB=A1=9C=20=EC=84=A4=EC=A0=95=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index dc9f2604..01b04e32 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -15,6 +15,11 @@ jobs: build: runs-on: ubuntu-latest + defaults: + run: + shell: bash + working-directory: ./backend + steps: - name: Checkout code uses: actions/checkout@v4 From 95ac7d5521feed1048e4e1d3a3dd67e2bace4cec Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 17:34:56 +0900 Subject: [PATCH 0146/1013] =?UTF-8?q?fix:=20checkout=20with=20=EC=98=B5?= =?UTF-8?q?=EC=85=98,=20=EB=B2=84=EC=A0=84=EC=97=85=EC=97=90=20=EB=94=B0?= =?UTF-8?q?=EB=A5=B8=20=EC=84=A4=EC=A0=95=20=EB=B3=80=EA=B2=BD=20=EB=82=B4?= =?UTF-8?q?=EC=9A=A9=20=EB=B0=98=EC=98=81=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 10 ++++------ .github/workflows/be-ci-dev.yml | 9 ++++----- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 01b04e32..04da6e12 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -21,14 +21,12 @@ jobs: working-directory: ./backend steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Set up JDK 17 - uses: actions/setup-java@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: - java-version: '17' distribution: 'temurin' + java-version: '17' - name: Grant execute permission for gradlew run: chmod +x gradlew @@ -51,7 +49,7 @@ jobs: deploy: needs: build - runs-on: [self-hosted, linux, ARM64] # Self hosted runner 사용 + runs-on: [ self-hosted, linux, ARM64 ] # Self hosted runner 사용 steps: - name: Pull docker image run: sudo docker pull ${{ secrets.DOCKER_USERNAME }}/ddangkong-api-dev:latest \ No newline at end of file diff --git a/.github/workflows/be-ci-dev.yml b/.github/workflows/be-ci-dev.yml index dfad31e4..ece9ddbd 100644 --- a/.github/workflows/be-ci-dev.yml +++ b/.github/workflows/be-ci-dev.yml @@ -21,17 +21,16 @@ jobs: working-directory: ./backend steps: - - name: checkout - uses: actions/checkout@v4 - - name: Set up JDK 17 - uses: actions/setup-java@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: - java-version: '17' distribution: 'temurin' + java-version: '17' - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build with Gradle run: ./gradlew clean build + From 2b38e3f3ecd90aadcd9e8e1595a153cd5224a49d Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 17:38:45 +0900 Subject: [PATCH 0147/1013] =?UTF-8?q?fix:=20checkout=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 9 +++++---- .github/workflows/be-ci-dev.yml | 6 ++++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 04da6e12..886d4b80 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -21,9 +21,11 @@ jobs: working-directory: ./backend steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Set up JDK 17 - - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 + uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '17' @@ -41,12 +43,11 @@ jobs: password: ${{ secrets.DOCKER_PASSWORD }} - name: Build Docker image - run: docker build ./Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/ddangkong-api-dev:latest + run: docker build -t ${{ secrets.DOCKER_USERNAME }}/ddangkong-api-dev:latest . - name: Push Docker image run: docker push ${{ secrets.DOCKER_USERNAME }}/ddangkong-api-dev:latest - deploy: needs: build runs-on: [ self-hosted, linux, ARM64 ] # Self hosted runner 사용 diff --git a/.github/workflows/be-ci-dev.yml b/.github/workflows/be-ci-dev.yml index ece9ddbd..3c0f6257 100644 --- a/.github/workflows/be-ci-dev.yml +++ b/.github/workflows/be-ci-dev.yml @@ -21,9 +21,11 @@ jobs: working-directory: ./backend steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Set up JDK 17 - - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 + uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '17' From a7d1657eae14d99672de2c5645f6bf479852aa61 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 18:55:44 +0900 Subject: [PATCH 0148/1013] =?UTF-8?q?fix:=20CD=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=BD=ED=8A=B8=20docker=20mail,=20repositoryName=20?= =?UTF-8?q?=EA=B5=AC=EB=B6=84=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 886d4b80..61acc377 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -39,18 +39,18 @@ jobs: - name: Log in to Docker Hub uses: docker/login-action@v3 with: - username: ${{ secrets.DOCKER_USERNAME }} + username: ${{ secrets.DOCKER_GMAIL }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build Docker image - run: docker build -t ${{ secrets.DOCKER_USERNAME }}/ddangkong-api-dev:latest . + run: docker build -t ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest . - name: Push Docker image - run: docker push ${{ secrets.DOCKER_USERNAME }}/ddangkong-api-dev:latest + run: docker push ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest deploy: needs: build runs-on: [ self-hosted, linux, ARM64 ] # Self hosted runner 사용 steps: - name: Pull docker image - run: sudo docker pull ${{ secrets.DOCKER_USERNAME }}/ddangkong-api-dev:latest \ No newline at end of file + run: sudo docker pull ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest \ No newline at end of file From dd7d47f43dee593356bf32c51db109247026f613 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 19:06:02 +0900 Subject: [PATCH 0149/1013] =?UTF-8?q?fix:=20Dockerfile=2017=EB=B2=84?= =?UTF-8?q?=EC=A0=84=20jre=EA=B0=80=20=EC=97=86=EC=9C=BC=EB=AF=80=EB=A1=9C?= =?UTF-8?q?=20jdk=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index ddec20a8..44ae8197 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,5 +1,5 @@ # Use an official OpenJDK runtime as a parent image -FROM openjdk:17-jre-slim +FROM openjdk:17-jdk-slim # Copy the jar file into the container COPY build/libs/*.jar app.jar From 0eac0bd69fb1ad32b197caba45d650ad240bf8f6 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 19:13:36 +0900 Subject: [PATCH 0150/1013] =?UTF-8?q?chore:=20DOCKER=5FPASSWORD=20->=20DOC?= =?UTF-8?q?KER=5FTOKEN=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 61acc377..d6568a8f 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -40,7 +40,7 @@ jobs: uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_GMAIL }} - password: ${{ secrets.DOCKER_PASSWORD }} + password: ${{ secrets.DOCKER_TOKEN }} - name: Build Docker image run: docker build -t ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest . From 205892cecd4156eab51ea1867e0f24bc55d63dbe Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 19:48:44 +0900 Subject: [PATCH 0151/1013] =?UTF-8?q?feat:=20=EB=8F=84=EC=BB=A4=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20build=20=EC=8B=9C,=20linux/amd64?= =?UTF-8?q?=20=ED=98=B8=ED=99=98=EC=84=B1=20=EC=84=A4=EC=A0=95=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index d6568a8f..63dacbe1 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -43,7 +43,7 @@ jobs: password: ${{ secrets.DOCKER_TOKEN }} - name: Build Docker image - run: docker build -t ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest . + run: docker build .Dockerfile --platform linux/amd64 -t ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest . - name: Push Docker image run: docker push ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest @@ -52,5 +52,6 @@ jobs: needs: build runs-on: [ self-hosted, linux, ARM64 ] # Self hosted runner 사용 steps: + - - name: Pull docker image run: sudo docker pull ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest \ No newline at end of file From 55a592e768b0b1fe401a5df15bebaa4b64de2e9d Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 19:50:27 +0900 Subject: [PATCH 0152/1013] =?UTF-8?q?fix:=20=EA=B3=B5=EB=B0=B1=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 63dacbe1..2f3db457 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -52,6 +52,5 @@ jobs: needs: build runs-on: [ self-hosted, linux, ARM64 ] # Self hosted runner 사용 steps: - - - name: Pull docker image run: sudo docker pull ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest \ No newline at end of file From 66fc613402f9206a4acb34a51a1bffe4ef61e534 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 19:55:32 +0900 Subject: [PATCH 0153/1013] =?UTF-8?q?fix:=20Dockerfile=20=EA=B2=BD?= =?UTF-8?q?=EB=A1=9C=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 2f3db457..16ecc2ba 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -43,7 +43,7 @@ jobs: password: ${{ secrets.DOCKER_TOKEN }} - name: Build Docker image - run: docker build .Dockerfile --platform linux/amd64 -t ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest . + run: docker build ./Dockerfile --platform linux/amd64 -t ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest . - name: Push Docker image run: docker push ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest From 298e1340c07aa17d260fb2ebcf15c1d25eed68f6 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 19:57:38 +0900 Subject: [PATCH 0154/1013] =?UTF-8?q?fix:=20Dockerfile=20=EA=B2=BD?= =?UTF-8?q?=EB=A1=9C=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 16ecc2ba..8f2d9ed0 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -43,7 +43,7 @@ jobs: password: ${{ secrets.DOCKER_TOKEN }} - name: Build Docker image - run: docker build ./Dockerfile --platform linux/amd64 -t ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest . + run: docker build ./Dockerfile --platform linux/amd64 -t ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest - name: Push Docker image run: docker push ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest From f2d56f1acbe87c9b3aeea361df3361733981f72e Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 20:19:07 +0900 Subject: [PATCH 0155/1013] =?UTF-8?q?fix:=20Dockerfile=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EC=83=81=20=EC=9C=84=EC=B9=98=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 8f2d9ed0..2b68811a 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -43,7 +43,7 @@ jobs: password: ${{ secrets.DOCKER_TOKEN }} - name: Build Docker image - run: docker build ./Dockerfile --platform linux/amd64 -t ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest + run: docker build --platform linux/amd64 ./Dockerfile -t ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest - name: Push Docker image run: docker push ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest From 9b504fc2e8dfde34ab6aa7d0d60c7b2319333696 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 20:22:20 +0900 Subject: [PATCH 0156/1013] =?UTF-8?q?fix:=20Dockerfile=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EC=83=81=20=EC=9C=84=EC=B9=98=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 2b68811a..5f1c7b4e 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -43,7 +43,7 @@ jobs: password: ${{ secrets.DOCKER_TOKEN }} - name: Build Docker image - run: docker build --platform linux/amd64 ./Dockerfile -t ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest + run: docker build --platform linux/amd64 -t ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest . - name: Push Docker image run: docker push ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest From b372a448d91238ca633a32e66b9fa4be2bad92a6 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 20:29:19 +0900 Subject: [PATCH 0157/1013] =?UTF-8?q?fix:=20Dockerfile=20ENTRYPOINT=20?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=B0=B1=EA=B7=B8=EB=9D=BC=EC=9A=B4?= =?UTF-8?q?=EB=93=9C=20=EC=8B=A4=ED=96=89=20=EB=AA=85=EB=A0=B9=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 44ae8197..aaa4ca48 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -8,4 +8,4 @@ COPY build/libs/*.jar app.jar EXPOSE 8080 # Run the jar file -ENTRYPOINT ["nohup", "java", "-jar", "-Duser.timezone=Asia/Seoul","-Dspring.profiles.active=dev", "app.jar", "&"] +ENTRYPOINT ["java", "-jar", "-Duser.timezone=Asia/Seoul","-Dspring.profiles.active=dev", "app.jar"] From 04ba3fabeb6557f0cb57032ede16e56fcf05ed92 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 20:36:23 +0900 Subject: [PATCH 0158/1013] =?UTF-8?q?chore:=20dockerfile=20build=20image?= =?UTF-8?q?=20platform=20linux/arm64/v8=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20#3?= =?UTF-8?q?3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 5f1c7b4e..06d70018 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -43,7 +43,7 @@ jobs: password: ${{ secrets.DOCKER_TOKEN }} - name: Build Docker image - run: docker build --platform linux/amd64 -t ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest . + run: docker build --platform linux/arm64/v8 -t ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest . - name: Push Docker image run: docker push ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest From 0f01a666a89cbdc1338c572d0c13a40ed1da51ea Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 21:42:33 +0900 Subject: [PATCH 0159/1013] =?UTF-8?q?feat:=20docker=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=EB=A5=BC=20=EC=82=AC=EC=9A=A9=ED=95=9C=20=EB=B0=B0?= =?UTF-8?q?=ED=8F=AC=20=EC=8A=A4=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 06d70018..e1e51237 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -51,6 +51,21 @@ jobs: deploy: needs: build runs-on: [ self-hosted, linux, ARM64 ] # Self hosted runner 사용 + steps: + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_GMAIL }} + password: ${{ secrets.DOCKER_TOKEN }} + env: + CONTAINER_NAME: ddangkong-api-dev + - name: Pull docker image - run: sudo docker pull ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest \ No newline at end of file + run: sudo docker pull ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest + + - name: Stop and Remove previous Docker container + run: sudo docker rm -f $CONTAINER_NAME + + - name: Run new Docker container + run: sudo docker run -d --name $CONTAINER_NAME -p 8080:8080 ddangkong/ddangkong-api-dev:latest \ No newline at end of file From 43f2efb87da6834b7418c1b8f640a2aec2ed6cc5 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 21:51:50 +0900 Subject: [PATCH 0160/1013] =?UTF-8?q?fix:=20docker=20rm=20=EB=AA=85?= =?UTF-8?q?=EB=A0=B9=EC=96=B4=20containerId=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index e1e51237..7f2d9daf 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -65,7 +65,9 @@ jobs: run: sudo docker pull ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest - name: Stop and Remove previous Docker container - run: sudo docker rm -f $CONTAINER_NAME + run: | + CONTAINER_ID=$(sudo docker ps -aqf "name=$CONTAINER_NAME") + sudo docker rm -f ${CONTAINER_ID} - name: Run new Docker container run: sudo docker run -d --name $CONTAINER_NAME -p 8080:8080 ddangkong/ddangkong-api-dev:latest \ No newline at end of file From 64a564218815a5ad7c33ae494ee758feff5c1261 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 22:03:20 +0900 Subject: [PATCH 0161/1013] =?UTF-8?q?fix:=20env=20=ED=99=98=EA=B2=BD?= =?UTF-8?q?=EB=B3=80=EC=88=98=20=EC=82=AC=EC=9A=A9=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 7f2d9daf..62d079c2 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -66,8 +66,11 @@ jobs: - name: Stop and Remove previous Docker container run: | - CONTAINER_ID=$(sudo docker ps -aqf "name=$CONTAINER_NAME") + CONTAINER_ID=$(sudo docker ps -aqf "name=${{ env.CONTAINER_NAME }}") sudo docker rm -f ${CONTAINER_ID} - name: Run new Docker container - run: sudo docker run -d --name $CONTAINER_NAME -p 8080:8080 ddangkong/ddangkong-api-dev:latest \ No newline at end of file + run: | + sudo docker run -d --name ${{ env.CONTAINER_NAME }} \ + -p 8080:8080 \ + ddangkong/ddangkong-api-dev:latest \ No newline at end of file From a0b9c229637543844a92efacb16d9e64b73dff9f Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 22:05:18 +0900 Subject: [PATCH 0162/1013] =?UTF-8?q?fix:=20env=20=ED=99=98=EA=B2=BD?= =?UTF-8?q?=EB=B3=80=EC=88=98=20=EC=82=AC=EC=9A=A9=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 62d079c2..15560fdd 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -66,7 +66,7 @@ jobs: - name: Stop and Remove previous Docker container run: | - CONTAINER_ID=$(sudo docker ps -aqf "name=${{ env.CONTAINER_NAME }}") + CONTAINER_ID=$(sudo docker ps -aqf "name=$CONTAINER_NAME") sudo docker rm -f ${CONTAINER_ID} - name: Run new Docker container From bb0e5865f5d2b8d62dda36c4f77c3bf25e5b65f3 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 22:10:13 +0900 Subject: [PATCH 0163/1013] =?UTF-8?q?fix:=20env=20=ED=99=98=EA=B2=BD?= =?UTF-8?q?=EB=B3=80=EC=88=98=20=EC=82=AC=EC=9A=A9=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 15560fdd..5ea8318b 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -58,19 +58,17 @@ jobs: with: username: ${{ secrets.DOCKER_GMAIL }} password: ${{ secrets.DOCKER_TOKEN }} - env: - CONTAINER_NAME: ddangkong-api-dev - name: Pull docker image run: sudo docker pull ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest - name: Stop and Remove previous Docker container run: | - CONTAINER_ID=$(sudo docker ps -aqf "name=$CONTAINER_NAME") + CONTAINER_ID=$(sudo docker ps -aqf "name=ddangkong-api-dev") sudo docker rm -f ${CONTAINER_ID} - name: Run new Docker container run: | - sudo docker run -d --name ${{ env.CONTAINER_NAME }} \ + sudo docker run -d --name ddangkong-api-dev \ -p 8080:8080 \ ddangkong/ddangkong-api-dev:latest \ No newline at end of file From 2f3da0192853458cc63e51115da819244552cc3c Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 18 Jul 2024 22:18:32 +0900 Subject: [PATCH 0164/1013] =?UTF-8?q?fix:=20=EC=8B=A4=ED=96=89=EC=A4=91?= =?UTF-8?q?=EC=9D=B8=20=EC=BB=A8=ED=85=8C=EC=9D=B4=EB=84=88=EA=B0=80=20?= =?UTF-8?q?=EC=97=86=EC=9C=BC=EB=A9=B4=20=EC=BB=A8=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=84=88=20rm=20=EC=9E=91=EC=97=85=20=EC=8A=A4=ED=82=B5?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EA=B5=AC=ED=98=84=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 5ea8318b..3276a722 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -58,6 +58,8 @@ jobs: with: username: ${{ secrets.DOCKER_GMAIL }} password: ${{ secrets.DOCKER_TOKEN }} + env: + CONTAINER_NAME: ddangkong-api-dev - name: Pull docker image run: sudo docker pull ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest @@ -65,7 +67,11 @@ jobs: - name: Stop and Remove previous Docker container run: | CONTAINER_ID=$(sudo docker ps -aqf "name=ddangkong-api-dev") + if [ -n "$CONTAINER_ID" ]; then sudo docker rm -f ${CONTAINER_ID} + else + echo "No previous container found with name. Skipping removal." + fi - name: Run new Docker container run: | From ebda3a9586cb8b28ef389f104bd7962d0dfa0056 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Fri, 19 Jul 2024 19:56:34 +0900 Subject: [PATCH 0165/1013] =?UTF-8?q?chore:=20gradle=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20clean=20=EB=AA=85=EB=A0=B9=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 +- .github/workflows/be-ci-dev.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 3276a722..143b682b 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -34,7 +34,7 @@ jobs: run: chmod +x gradlew - name: Build with Gradle - run: ./gradlew clean bootJar + run: ./gradlew bootJar - name: Log in to Docker Hub uses: docker/login-action@v3 diff --git a/.github/workflows/be-ci-dev.yml b/.github/workflows/be-ci-dev.yml index 3c0f6257..eeb9e174 100644 --- a/.github/workflows/be-ci-dev.yml +++ b/.github/workflows/be-ci-dev.yml @@ -34,5 +34,5 @@ jobs: run: chmod +x gradlew - name: Build with Gradle - run: ./gradlew clean build + run: ./gradlew build From d07d9b736b2bf80826e127e86b572c5ced17ac03 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Fri, 19 Jul 2024 20:01:09 +0900 Subject: [PATCH 0166/1013] =?UTF-8?q?chore:=20Dockerfile=20=EB=B6=88?= =?UTF-8?q?=ED=95=84=EC=9A=94=ED=95=9C=20EXPOSE=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0=20#3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/Dockerfile | 3 --- 1 file changed, 3 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index aaa4ca48..09cb3c5b 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -4,8 +4,5 @@ FROM openjdk:17-jdk-slim # Copy the jar file into the container COPY build/libs/*.jar app.jar -# Make port 8080 available to the world outside this container -EXPOSE 8080 - # Run the jar file ENTRYPOINT ["java", "-jar", "-Duser.timezone=Asia/Seoul","-Dspring.profiles.active=dev", "app.jar"] From 2bcc0f7b2a944359a57e86308fd354ed62c3b8af Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Fri, 19 Jul 2024 20:01:17 +0900 Subject: [PATCH 0167/1013] =?UTF-8?q?chore:=20EOF=20=EC=B6=94=EA=B0=80=20#?= =?UTF-8?q?33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 +- .github/workflows/be-ci-dev.yml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 143b682b..c007d063 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -77,4 +77,4 @@ jobs: run: | sudo docker run -d --name ddangkong-api-dev \ -p 8080:8080 \ - ddangkong/ddangkong-api-dev:latest \ No newline at end of file + ddangkong/ddangkong-api-dev:latest diff --git a/.github/workflows/be-ci-dev.yml b/.github/workflows/be-ci-dev.yml index eeb9e174..50441dc8 100644 --- a/.github/workflows/be-ci-dev.yml +++ b/.github/workflows/be-ci-dev.yml @@ -35,4 +35,3 @@ jobs: - name: Build with Gradle run: ./gradlew build - From 1fc41c71aa3fad21ee11858d098366a99879d2a5 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Sat, 20 Jul 2024 14:25:47 +0900 Subject: [PATCH 0168/1013] =?UTF-8?q?refactor:=20docker-compose=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=98=EC=97=AC=20dev=20=ED=99=98=EA=B2=BD?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 5 +++-- backend/Dockerfile | 11 +++++------ backend/deploy/docker-compose-dev.yml | 11 +++++++++++ 3 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 backend/deploy/docker-compose-dev.yml diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index c007d063..7792f870 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -43,7 +43,9 @@ jobs: password: ${{ secrets.DOCKER_TOKEN }} - name: Build Docker image - run: docker build --platform linux/arm64/v8 -t ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest . + run: | + docker compose -f deploy/docker-compose-dev.yml build + docker tag deploy-ddangkong-api-dev:latest ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest - name: Push Docker image run: docker push ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest @@ -76,5 +78,4 @@ jobs: - name: Run new Docker container run: | sudo docker run -d --name ddangkong-api-dev \ - -p 8080:8080 \ ddangkong/ddangkong-api-dev:latest diff --git a/backend/Dockerfile b/backend/Dockerfile index 09cb3c5b..1601fa0d 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,8 +1,7 @@ -# Use an official OpenJDK runtime as a parent image FROM openjdk:17-jdk-slim -# Copy the jar file into the container -COPY build/libs/*.jar app.jar - -# Run the jar file -ENTRYPOINT ["java", "-jar", "-Duser.timezone=Asia/Seoul","-Dspring.profiles.active=dev", "app.jar"] +ARG JAR_FILE=build/libs/*.jar + +COPY ${JAR_FILE} app.jar + +ENTRYPOINT [ "java", "-jar", "-Duser.timezone=Asia/Seoul", "app.jar" ] \ No newline at end of file diff --git a/backend/deploy/docker-compose-dev.yml b/backend/deploy/docker-compose-dev.yml new file mode 100644 index 00000000..534cc452 --- /dev/null +++ b/backend/deploy/docker-compose-dev.yml @@ -0,0 +1,11 @@ +version: "2.29.0" + +services: + ddangkong-api-dev: + platform: linux/arm64/v8 + build: + context: ../ + dockerfile: Dockerfile + entrypoint: [ java, -jar, -Dspring.profiles.active=dev, -Duser.timezone=Asia/Seoul, app.jar ] + ports: + - "8080:8080" \ No newline at end of file From ef08a0bffc35067399286158291c4e2be2f356bd Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Sat, 20 Jul 2024 16:23:06 +0900 Subject: [PATCH 0169/1013] =?UTF-8?q?chore:=20CONTAINER=5FNAME,=20DOCKER?= =?UTF-8?q?=5FREPOSITORY=5FNAME=20env=EB=A1=9C=20=EC=82=AC=EC=9A=A9=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 7792f870..9f885bc3 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -14,6 +14,8 @@ permissions: jobs: build: runs-on: ubuntu-latest + env: + DOCKER_REPOSITORY_NAME: ddangkong/ddangkong-api-dev defaults: run: @@ -44,15 +46,18 @@ jobs: - name: Build Docker image run: | - docker compose -f deploy/docker-compose-dev.yml build - docker tag deploy-ddangkong-api-dev:latest ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest + docker compose -f deploy/docker-compose-dev.yml build + docker tag deploy-ddangkong-api-dev:latest $DOCKER_REPOSITORY_NAME:latest - name: Push Docker image - run: docker push ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest + run: docker push $DOCKER_REPOSITORY_NAME:latest deploy: needs: build runs-on: [ self-hosted, linux, ARM64 ] # Self hosted runner 사용 + env: + DOCKER_REPOSITORY_NAME: ddangkong/ddangkong-api-dev + CONTAINER_NAME: ddangkong-api-dev steps: - name: Log in to Docker Hub @@ -60,16 +65,14 @@ jobs: with: username: ${{ secrets.DOCKER_GMAIL }} password: ${{ secrets.DOCKER_TOKEN }} - env: - CONTAINER_NAME: ddangkong-api-dev - name: Pull docker image - run: sudo docker pull ${{ secrets.DOCKER_REPOSITORY_NAME }}/ddangkong-api-dev:latest + run: sudo docker pull $DOCKER_REPOSITORY_NAME:latest - name: Stop and Remove previous Docker container run: | - CONTAINER_ID=$(sudo docker ps -aqf "name=ddangkong-api-dev") - if [ -n "$CONTAINER_ID" ]; then + CONTAINER_ID=$(sudo docker ps -aqf name=$CONTAINER_NAME) + if [ -n ${CONTAINER_ID} ]; then sudo docker rm -f ${CONTAINER_ID} else echo "No previous container found with name. Skipping removal." @@ -77,5 +80,5 @@ jobs: - name: Run new Docker container run: | - sudo docker run -d --name ddangkong-api-dev \ - ddangkong/ddangkong-api-dev:latest + sudo docker run -d --name $CONTAINER_NAME \ + $DOCKER_REPOSITORY_NAME:latest From a121b382eae7ad21b70a9e8277573b863746cf69 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Sat, 20 Jul 2024 16:33:22 +0900 Subject: [PATCH 0170/1013] =?UTF-8?q?chore:=20EOF=20=EC=B6=94=EA=B0=80=20#?= =?UTF-8?q?33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/Dockerfile | 2 +- backend/deploy/docker-compose-dev.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 1601fa0d..9b24fcf7 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -4,4 +4,4 @@ ARG JAR_FILE=build/libs/*.jar COPY ${JAR_FILE} app.jar -ENTRYPOINT [ "java", "-jar", "-Duser.timezone=Asia/Seoul", "app.jar" ] \ No newline at end of file +ENTRYPOINT [ "java", "-jar", "-Duser.timezone=Asia/Seoul", "app.jar" ] diff --git a/backend/deploy/docker-compose-dev.yml b/backend/deploy/docker-compose-dev.yml index 534cc452..82e96820 100644 --- a/backend/deploy/docker-compose-dev.yml +++ b/backend/deploy/docker-compose-dev.yml @@ -8,4 +8,4 @@ services: dockerfile: Dockerfile entrypoint: [ java, -jar, -Dspring.profiles.active=dev, -Duser.timezone=Asia/Seoul, app.jar ] ports: - - "8080:8080" \ No newline at end of file + - "8080:8080" From 5ed67038c461a17798e83f4716aa5a0386df60de Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Mon, 22 Jul 2024 17:36:57 +0900 Subject: [PATCH 0171/1013] =?UTF-8?q?chore:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20permissions=20=EC=84=A4=EC=A0=95=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 3 --- .github/workflows/be-ci-dev.yml | 3 --- 2 files changed, 6 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 9f885bc3..e9802f7c 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -8,9 +8,6 @@ on: paths: - backend/** -permissions: - contents: read - jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/be-ci-dev.yml b/.github/workflows/be-ci-dev.yml index 50441dc8..d1998382 100644 --- a/.github/workflows/be-ci-dev.yml +++ b/.github/workflows/be-ci-dev.yml @@ -8,9 +8,6 @@ on: paths: - backend/** -permissions: - contents: read - jobs: build: runs-on: ubuntu-latest From 5a210841d942c186638bad7fa9e013b6fb4f0034 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Mon, 22 Jul 2024 17:41:44 +0900 Subject: [PATCH 0172/1013] =?UTF-8?q?chore:=20Git=20Actions=EC=97=90?= =?UTF-8?q?=EC=84=9C=20Ubuntu=20=EA=B8=B0=EB=B3=B8=20shell=EC=9D=B4=20bash?= =?UTF-8?q?=EC=9D=B4=EA=B8=B0=20=EB=95=8C=EB=AC=B8=EC=97=90=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#defaults --- .github/workflows/be-ci-dev.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/be-ci-dev.yml b/.github/workflows/be-ci-dev.yml index d1998382..136ca32e 100644 --- a/.github/workflows/be-ci-dev.yml +++ b/.github/workflows/be-ci-dev.yml @@ -14,7 +14,6 @@ jobs: defaults: run: - shell: bash working-directory: ./backend steps: From fe7d08456e875e7736cfacf4cfe53c46f6adcf0a Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Mon, 22 Jul 2024 17:55:10 +0900 Subject: [PATCH 0173/1013] =?UTF-8?q?chore:=20Git=20Actions=EC=97=90?= =?UTF-8?q?=EC=84=9C=20Ubuntu=20=EA=B8=B0=EB=B3=B8=20shell=EC=9D=B4=20bash?= =?UTF-8?q?=EC=9D=B4=EA=B8=B0=20=EB=95=8C=EB=AC=B8=EC=97=90=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#defaults --- .github/workflows/be-cd-dev.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index e9802f7c..535e4de4 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -16,7 +16,6 @@ jobs: defaults: run: - shell: bash working-directory: ./backend steps: From 1d29099f2bdcfabfb45d931f3f870fb7a129f6ca Mon Sep 17 00:00:00 2001 From: jhon3242 Date: Mon, 22 Jul 2024 17:58:37 +0900 Subject: [PATCH 0174/1013] =?UTF-8?q?chore:=20entrypoint=20profile=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=A4=91=EB=B3=B5=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0=20#33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/Dockerfile | 5 ++++- backend/deploy/docker-compose-dev.yml | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 9b24fcf7..2e224430 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,7 +1,10 @@ FROM openjdk:17-jdk-slim ARG JAR_FILE=build/libs/*.jar +ARG SPRING_PROFILE + +ENV SPRING_PROFILE=${SPRING_PROFILE} COPY ${JAR_FILE} app.jar -ENTRYPOINT [ "java", "-jar", "-Duser.timezone=Asia/Seoul", "app.jar" ] +ENTRYPOINT [ "java", "-jar", "-Duser.timezone=Asia/Seoul", "-Dspring.profiles.active=${SPRING_PROFILE}", "app.jar" ] diff --git a/backend/deploy/docker-compose-dev.yml b/backend/deploy/docker-compose-dev.yml index 82e96820..3c84c791 100644 --- a/backend/deploy/docker-compose-dev.yml +++ b/backend/deploy/docker-compose-dev.yml @@ -6,6 +6,7 @@ services: build: context: ../ dockerfile: Dockerfile - entrypoint: [ java, -jar, -Dspring.profiles.active=dev, -Duser.timezone=Asia/Seoul, app.jar ] + args: + - SPRINT_PROFILE=dev ports: - "8080:8080" From aeb97fe9e03da2deac83cec5ee3ec173e3a33068 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Tue, 23 Jul 2024 16:01:30 +0900 Subject: [PATCH 0175/1013] =?UTF-8?q?build:=20recoil=20=EC=84=A4=EC=B9=98?= =?UTF-8?q?=20#47?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/package-lock.json | 27 ++++++++++++++++++++++++++- frontend/package.json | 3 ++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 102f796c..6ddf923f 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -13,7 +13,8 @@ "@tanstack/react-query": "^5.51.1", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-router-dom": "^6.24.1" + "react-router-dom": "^6.24.1", + "recoil": "^0.7.7" }, "devDependencies": { "@babel/cli": "^7.24.8", @@ -11197,6 +11198,11 @@ "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } }, + "node_modules/hamt_plus": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hamt_plus/-/hamt_plus-1.0.2.tgz", + "integrity": "sha512-t2JXKaehnMb9paaYA7J0BX8QQAY8lwfQ9Gjf4pg/mk4krt+cmwmU652HOoWonf+7+EQV97ARPMhhVgU1ra2GhA==" + }, "node_modules/handle-thing": { "version": "2.0.1", "dev": true, @@ -16826,6 +16832,25 @@ "node": ">= 10.13.0" } }, + "node_modules/recoil": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/recoil/-/recoil-0.7.7.tgz", + "integrity": "sha512-8Og5KPQW9LwC577Vc7Ug2P0vQshkv1y3zG3tSSkWMqkWSwHmE+by06L8JtnGocjW6gcCvfwB3YtrJG6/tWivNQ==", + "dependencies": { + "hamt_plus": "1.0.2" + }, + "peerDependencies": { + "react": ">=16.13.1" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, "node_modules/redent": { "version": "3.0.0", "dev": true, diff --git a/frontend/package.json b/frontend/package.json index e9a32bb8..e11f74c5 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -23,7 +23,8 @@ "@tanstack/react-query": "^5.51.1", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-router-dom": "^6.24.1" + "react-router-dom": "^6.24.1", + "recoil": "^0.7.7" }, "devDependencies": { "@babel/cli": "^7.24.8", From fa51ac474a61dbd8d297a55e93b78be0a5439f40 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Tue, 23 Jul 2024 16:05:58 +0900 Subject: [PATCH 0176/1013] =?UTF-8?q?feat:=20recoil=20Provider=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=20#47?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/index.tsx | 11 +++++++---- frontend/src/mocks/wrapper.tsx | 11 +++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 51622577..ebbb031e 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -1,6 +1,7 @@ import { Global, ThemeProvider } from '@emotion/react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import ReactDOM from 'react-dom/client'; +import { RecoilRoot } from 'recoil'; import App from './App'; import GlobalStyle from './styles/GlobalStyle'; @@ -21,10 +22,12 @@ const enableMocking = async () => { enableMocking().then(() => { ReactDOM.createRoot(document.getElementById('root')!).render( - - - - + + + + + + , ); }); diff --git a/frontend/src/mocks/wrapper.tsx b/frontend/src/mocks/wrapper.tsx index 1a9ac015..62a3f0c3 100644 --- a/frontend/src/mocks/wrapper.tsx +++ b/frontend/src/mocks/wrapper.tsx @@ -1,6 +1,7 @@ import { Global, ThemeProvider } from '@emotion/react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { PropsWithChildren } from 'react'; +import { RecoilRoot } from 'recoil'; import GlobalStyle from '@/styles/GlobalStyle'; import { Theme } from '@/styles/Theme'; @@ -16,10 +17,12 @@ const queryClient = new QueryClient({ const wrapper = ({ children }: PropsWithChildren) => { return ( - - - {children} - + + + + {children} + + ); }; From 790b3fd9a34800544740d2b7d827af14370eb518 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Tue, 23 Jul 2024 01:26:57 +0900 Subject: [PATCH 0177/1013] =?UTF-8?q?test:=20database=20cleaner=20extensio?= =?UTF-8?q?n=20=EC=B6=94=EA=B0=80=20#37?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../extension/DatabaseCleanerExtension.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 backend/src/test/java/ddangkong/support/extension/DatabaseCleanerExtension.java diff --git a/backend/src/test/java/ddangkong/support/extension/DatabaseCleanerExtension.java b/backend/src/test/java/ddangkong/support/extension/DatabaseCleanerExtension.java new file mode 100644 index 00000000..d9386b57 --- /dev/null +++ b/backend/src/test/java/ddangkong/support/extension/DatabaseCleanerExtension.java @@ -0,0 +1,47 @@ +package ddangkong.support.extension; + +import jakarta.persistence.EntityManager; +import java.util.List; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.transaction.support.TransactionTemplate; + +public class DatabaseCleanerExtension implements BeforeEachCallback { + + @Override + public void beforeEach(ExtensionContext extensionContext) { + ApplicationContext context = SpringExtension.getApplicationContext(extensionContext); + cleanup(context); + } + + private void cleanup(ApplicationContext context) { + EntityManager em = context.getBean(EntityManager.class); + TransactionTemplate transactionTemplate = context.getBean(TransactionTemplate.class); + + transactionTemplate.execute(action -> { + em.clear(); + truncateTables(em); + return null; + }); + } + + private void truncateTables(EntityManager em) { + em.createNativeQuery("SET REFERENTIAL_INTEGRITY FALSE").executeUpdate(); + for (String tableName : findTableNames(em)) { + em.createNativeQuery("TRUNCATE TABLE %s RESTART IDENTITY".formatted(tableName)).executeUpdate(); + } + em.createNativeQuery("SET REFERENTIAL_INTEGRITY TRUE").executeUpdate(); + } + + @SuppressWarnings("unchecked") + private List findTableNames(EntityManager em) { + String tableSelectQuery = """ + SELECT TABLE_NAME + FROM INFORMATION_SCHEMA.TABLES + WHERE TABLE_SCHEMA = 'PUBLIC' + """; + return em.createNativeQuery(tableSelectQuery).getResultList(); + } +} From 2e395038c8208c449f0ae973fcbd0048f263a36f Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Tue, 23 Jul 2024 01:28:54 +0900 Subject: [PATCH 0178/1013] =?UTF-8?q?chore:=20ddl=20=EC=A0=9C=EA=B1=B0=20?= =?UTF-8?q?=EB=B0=8F=20formatting=20#37?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/test/resources/init-test.sql | 66 ++++++++++++------------ 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/backend/src/test/resources/init-test.sql b/backend/src/test/resources/init-test.sql index 90b21797..a583b8f4 100644 --- a/backend/src/test/resources/init-test.sql +++ b/backend/src/test/resources/init-test.sql @@ -1,34 +1,32 @@ -SET REFERENTIAL_INTEGRITY FALSE; - -TRUNCATE TABLE member; -TRUNCATE TABLE balance_option; -TRUNCATE TABLE balance_content; -TRUNCATE TABLE balance_vote; -TRUNCATE TABLE room; -TRUNCATE TABLE room_content; - -ALTER TABLE member ALTER COLUMN ID RESTART WITH 1; -ALTER TABLE balance_option ALTER COLUMN ID RESTART WITH 1; -ALTER TABLE balance_content ALTER COLUMN ID RESTART WITH 1; -ALTER TABLE balance_vote ALTER COLUMN ID RESTART WITH 1; -ALTER TABLE room ALTER COLUMN ID RESTART WITH 1; -ALTER TABLE room_content ALTER COLUMN ID RESTART WITH 1; - -INSERT INTO room() VALUES (); - -INSERT INTO member(nickname, room_id) -VALUES ('mohamedeu al katan', 1), ('deundeun', 1), ('rupi', 1), ('rapper lee', 1); - -INSERT INTO room_content(room_id, balance_content_id, created_at) -VALUES (1, 2, '2024-07-18 19:50:00.000'), (1, 1, '2024-07-18 20:00:00.000'); - -INSERT INTO balance_content(category, name) -VALUES ('EXAMPLE', '민초 vs 반민초'), ('EXAMPLE', '월 200 백수 vs 월 500 직장인'); - -INSERT INTO balance_option(name, balance_content_id) -VALUES ('민초', 1), ('반민초', 1), ('월 200 백수', 2), ('월 200 직장인', 2); - -INSERT INTO balance_vote(balance_option_id, member_id) -VALUES (4, 1), (4, 2), (4, 3), (4, 4), (1, 1), (1, 2), (1, 3), (2, 4); - -SET REFERENTIAL_INTEGRITY TRUE; +INSERT INTO room () +VALUES (); + +INSERT INTO member (nickname, room_id) +VALUES ('mohamedeu al katan', 1), + ('deundeun', 1), + ('rupi', 1), + ('rapper lee', 1); + +INSERT INTO balance_content (category, name) +VALUES ('EXAMPLE', '민초 vs 반민초'), + ('EXAMPLE', '월 200 백수 vs 월 500 직장인'); + +INSERT INTO room_content (room_id, balance_content_id, created_at) +VALUES (1, 2, '2024-07-18 19:50:00.000'), + (1, 1, '2024-07-18 20:00:00.000'); + +INSERT INTO balance_option (name, balance_content_id) +VALUES ('민초', 1), + ('반민초', 1), + ('월 200 백수', 2), + ('월 200 직장인', 2); + +INSERT INTO balance_vote (balance_option_id, member_id) +VALUES (4, 1), + (4, 2), + (4, 3), + (4, 4), + (1, 1), + (1, 2), + (1, 3), + (2, 4); From 9a239eb932bb80d07f583971291ad6590c1c1634 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Tue, 23 Jul 2024 01:29:25 +0900 Subject: [PATCH 0179/1013] =?UTF-8?q?test:=20extension=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=20#37?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/java/ddangkong/controller/BaseControllerTest.java | 7 ++++++- .../src/test/java/ddangkong/domain/BaseRepositoryTest.java | 3 +-- .../src/test/java/ddangkong/service/BaseServiceTest.java | 7 ++++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/backend/src/test/java/ddangkong/controller/BaseControllerTest.java b/backend/src/test/java/ddangkong/controller/BaseControllerTest.java index c7516b20..9568c379 100644 --- a/backend/src/test/java/ddangkong/controller/BaseControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/BaseControllerTest.java @@ -1,13 +1,18 @@ package ddangkong.controller; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + +import ddangkong.support.extension.DatabaseCleanerExtension; import io.restassured.RestAssured; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.test.context.jdbc.Sql; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ExtendWith(DatabaseCleanerExtension.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @Sql(scripts = "/init-test.sql") public abstract class BaseControllerTest { diff --git a/backend/src/test/java/ddangkong/domain/BaseRepositoryTest.java b/backend/src/test/java/ddangkong/domain/BaseRepositoryTest.java index 92a08076..9f35171e 100644 --- a/backend/src/test/java/ddangkong/domain/BaseRepositoryTest.java +++ b/backend/src/test/java/ddangkong/domain/BaseRepositoryTest.java @@ -4,7 +4,6 @@ import org.springframework.test.context.jdbc.Sql; @DataJpaTest -@Sql(scripts = "/init-test.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) +@Sql(scripts = "/init-test.sql") public abstract class BaseRepositoryTest { - } diff --git a/backend/src/test/java/ddangkong/service/BaseServiceTest.java b/backend/src/test/java/ddangkong/service/BaseServiceTest.java index 614232a7..3b52b23d 100644 --- a/backend/src/test/java/ddangkong/service/BaseServiceTest.java +++ b/backend/src/test/java/ddangkong/service/BaseServiceTest.java @@ -1,9 +1,14 @@ package ddangkong.service; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + +import ddangkong.support.extension.DatabaseCleanerExtension; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.jdbc.Sql; -@SpringBootTest +@ExtendWith(DatabaseCleanerExtension.class) +@SpringBootTest(webEnvironment = WebEnvironment.NONE) @Sql(scripts = "/init-test.sql") public abstract class BaseServiceTest { } From 1e01b1114feb6c1ee277558a0e294134ebaf91fa Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Tue, 23 Jul 2024 01:32:44 +0900 Subject: [PATCH 0180/1013] =?UTF-8?q?test:=20=EC=9E=98=EB=AA=BB=EB=90=9C?= =?UTF-8?q?=20=EB=B3=80=EC=88=98=EB=AA=85=20=EC=88=98=EC=A0=95=20#37?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/balance/content/RoomContentRepositoryTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/test/java/ddangkong/domain/balance/content/RoomContentRepositoryTest.java b/backend/src/test/java/ddangkong/domain/balance/content/RoomContentRepositoryTest.java index 67af2b4e..91d270eb 100644 --- a/backend/src/test/java/ddangkong/domain/balance/content/RoomContentRepositoryTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/content/RoomContentRepositoryTest.java @@ -18,10 +18,10 @@ class 방의_최신_질문_조회 { @Test void 방의_가장_최신의_질문을_조회할_수_있다() { // given - Long recentContentId = 1L; + Long roomId = 1L; // when - RoomContent actual = roomContentRepository.findTopByRoomIdOrderByCreatedAtDesc(recentContentId).get(); + RoomContent actual = roomContentRepository.findTopByRoomIdOrderByCreatedAtDesc(roomId).get(); // then assertThat(actual.getId()).isEqualTo(2L); From 05adff197933831b80c194725d804671fa42efd6 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Tue, 23 Jul 2024 02:17:58 +0900 Subject: [PATCH 0181/1013] =?UTF-8?q?test:=20=EB=B3=80=EC=88=98=EB=AA=85?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20#37?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ddangkong/support/extension/DatabaseCleanerExtension.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/test/java/ddangkong/support/extension/DatabaseCleanerExtension.java b/backend/src/test/java/ddangkong/support/extension/DatabaseCleanerExtension.java index d9386b57..0d153f34 100644 --- a/backend/src/test/java/ddangkong/support/extension/DatabaseCleanerExtension.java +++ b/backend/src/test/java/ddangkong/support/extension/DatabaseCleanerExtension.java @@ -37,11 +37,11 @@ private void truncateTables(EntityManager em) { @SuppressWarnings("unchecked") private List findTableNames(EntityManager em) { - String tableSelectQuery = """ + String tableNameSelectQuery = """ SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'PUBLIC' """; - return em.createNativeQuery(tableSelectQuery).getResultList(); + return em.createNativeQuery(tableNameSelectQuery).getResultList(); } } From 6e828d2b086688e728552e6ea56682665e62151d Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 24 Jul 2024 03:16:11 +0900 Subject: [PATCH 0182/1013] =?UTF-8?q?feat:=20borderRadius,=20typography=20?= =?UTF-8?q?=EB=94=94=EC=9E=90=EC=9D=B8=20=ED=86=A0=ED=81=B0=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20#49?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/styles/Theme.ts | 44 ++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/frontend/src/styles/Theme.ts b/frontend/src/styles/Theme.ts index fdf9bd95..f3bc0145 100644 --- a/frontend/src/styles/Theme.ts +++ b/frontend/src/styles/Theme.ts @@ -5,6 +5,50 @@ const color = { peanut500: '#FFD076', } as const; +export const borderRadius = { + none: '0', + radius10: '0.8rem', + radius20: '2rem', + radius30: '3.2rem', +} as const; + +export const typography = { + slogan: { + fontSize: '2.8rem', + fontWeight: 'bold', + }, + headline1: { + fontSize: '2.4rem', + fontWeight: 'bold', + }, + headline2: { + fontSize: '2rem', + fontWeight: 'bold', + }, + headline3: { + fontSize: '1.6rem', + fontWeight: 'bold', + }, + body1: { + fontSize: '1.6rem', + fontWeight: '500', + }, + body2: { + fontSize: '1.4rem', + fontWeight: '500', + }, + caption: { + fontSize: '1.2rem', + fontWeight: '500', + }, + placeholder: { + fontSize: '1.2rem', + fontWeight: '500', + }, +} as const; + export const Theme = { color, + borderRadius, + typography, }; From ff2f09b32781f9b2b51086d5f7289f8ea2cfdb3b Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 24 Jul 2024 03:22:39 +0900 Subject: [PATCH 0183/1013] =?UTF-8?q?refactor:=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=97=90=20size,=20radius,?= =?UTF-8?q?=20fontSize=20prop=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EC=A1=B0?= =?UTF-8?q?=EA=B1=B4=EB=B6=80=20=EC=8A=A4=ED=83=80=EC=9D=BC=EB=A7=81=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9=20#49?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/common/Button/Button.styled.ts | 30 +++++++++++++++---- .../src/components/common/Button/Button.tsx | 24 +++++++++++---- 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/frontend/src/components/common/Button/Button.styled.ts b/frontend/src/components/common/Button/Button.styled.ts index f4b54269..feba9977 100644 --- a/frontend/src/components/common/Button/Button.styled.ts +++ b/frontend/src/components/common/Button/Button.styled.ts @@ -2,12 +2,32 @@ import { css } from '@emotion/react'; import { Theme } from '@/styles/Theme'; -export const buttonLayout = (active: boolean) => css` - padding: 1rem 4rem; +interface ButtonLayoutProps { + disabled?: boolean; + size?: 'small' | 'medium' | 'large'; + radius?: 'none' | 'small' | 'medium' | 'large'; + fontSize?: 'small' | 'medium' | 'large'; +} - background-color: ${active ? Theme.color.peanut400 : Theme.color.peanut300}; +export const buttonLayout = ({ disabled, size, radius, fontSize }: ButtonLayoutProps) => css` + display: flex; + justify-content: center; + width: ${size === 'small' ? '6.9rem' : size === 'medium' ? '12rem' : '32rem'}; + padding: ${size === 'small' ? '0.8rem' : size === 'medium' ? '1.6rem' : '2rem'} 0; + + background-color: ${disabled ? Theme.color.peanut300 : Theme.color.peanut400}; font-weight: bold; - font-size: 2rem; - border-radius: 2.4rem; + font-size: ${fontSize === 'small' + ? Theme.typography.caption.fontSize + : size === 'medium' + ? Theme.typography.headline2.fontSize + : Theme.typography.headline1.fontSize}; + border-radius: ${radius === 'small' + ? Theme.borderRadius.radius10 + : radius === 'medium' + ? Theme.borderRadius.radius20 + : radius === 'large' + ? Theme.borderRadius.radius30 + : Theme.borderRadius.none}; `; diff --git a/frontend/src/components/common/Button/Button.tsx b/frontend/src/components/common/Button/Button.tsx index 804ec087..51daaea4 100644 --- a/frontend/src/components/common/Button/Button.tsx +++ b/frontend/src/components/common/Button/Button.tsx @@ -1,14 +1,28 @@ +import React, { ButtonHTMLAttributes } from 'react'; + import { buttonLayout } from './Button.styled'; -interface ButtonProps { - text: '선택' | '확인' | '다음'; - active: boolean; +interface ButtonProps extends ButtonHTMLAttributes { + text: string; onClick: () => void; + disabled?: boolean; + style?: React.CSSProperties; + size?: 'small' | 'medium' | 'large'; + radius?: 'none' | 'small' | 'medium' | 'large'; + fontSize?: 'small' | 'medium' | 'large'; } -const Button = ({ text, active, onClick }: ButtonProps) => { +const Button: React.FC = ({ + text, + onClick, + disabled = false, + size = 'large', + radius = 'none', + fontSize = 'medium', + ...props +}) => { return ( - ); From fcac114bcdd0819638c1fc1206124c2206c456eb Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 24 Jul 2024 03:25:15 +0900 Subject: [PATCH 0184/1013] =?UTF-8?q?test:=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=8A=A4=ED=86=A0?= =?UTF-8?q?=EB=A6=AC=EB=B6=81=20=EC=B6=94=EA=B0=80=20#49?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/Button/Button.stories.tsx | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 frontend/src/components/common/Button/Button.stories.tsx diff --git a/frontend/src/components/common/Button/Button.stories.tsx b/frontend/src/components/common/Button/Button.stories.tsx new file mode 100644 index 00000000..9e83e395 --- /dev/null +++ b/frontend/src/components/common/Button/Button.stories.tsx @@ -0,0 +1,36 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { fn } from '@storybook/test'; + +import Button from './Button'; + +const meta = { + title: 'Button', + parameters: { + argTypes: {}, + actions: { argTypesRegex: '^on.*' }, + }, + + args: { onClick: fn() }, + + component: Button, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const 클릭_가능한_버튼: Story = { + args: { + text: '확인', + }, + render: ({ ...args }) =>
); }; diff --git a/frontend/src/components/SelectContainer/SelectContainer.tsx b/frontend/src/components/SelectContainer/SelectContainer.tsx index 65eed145..edc2e264 100644 --- a/frontend/src/components/SelectContainer/SelectContainer.tsx +++ b/frontend/src/components/SelectContainer/SelectContainer.tsx @@ -39,7 +39,7 @@ const SelectContainer = () => { handleSelectOption={handleSelectOption} /> - + + ); }; export default MainPage; diff --git a/frontend/src/styles/GlobalStyle.ts b/frontend/src/styles/GlobalStyle.ts index f3217262..7c8fe3ef 100644 --- a/frontend/src/styles/GlobalStyle.ts +++ b/frontend/src/styles/GlobalStyle.ts @@ -143,7 +143,6 @@ const GlobalStyle = css` ${reset} html { - margin-top: 3rem; font-size: 10px; } From 561c10ab9f4eb1fed1a01ee9b81dc8cb84a91e3e Mon Sep 17 00:00:00 2001 From: novice0840 Date: Tue, 23 Jul 2024 19:01:35 +0900 Subject: [PATCH 0203/1013] feat: nickname page UI #46 --- .../pages/NicknamePage/NicknamePage.styled.ts | 39 +++++++++++++++++++ .../src/pages/NicknamePage/NicknamePage.tsx | 14 ++++++- 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 frontend/src/pages/NicknamePage/NicknamePage.styled.ts diff --git a/frontend/src/pages/NicknamePage/NicknamePage.styled.ts b/frontend/src/pages/NicknamePage/NicknamePage.styled.ts new file mode 100644 index 00000000..f2ad784c --- /dev/null +++ b/frontend/src/pages/NicknamePage/NicknamePage.styled.ts @@ -0,0 +1,39 @@ +import { css } from '@emotion/react'; + +import { Theme } from '@/styles/Theme'; + +export const profile = css` + width: 8rem; + height: 8rem; + margin-top: 4rem; + + background-color: ${Theme.color.gray300}; + border-radius: 50%; +`; + +export const nickname = css` + width: 26.8rem; + margin: 2rem 0; + + font-weight: 600; + font-size: 1.6rem; +`; + +export const nicknameInputWrapper = css` + display: flex; + align-items: center; + width: 26.8rem; + height: 4.9rem; + padding: 0 1rem; + + background-color: ${Theme.color.gray200}; + border-radius: 1rem; +`; + +export const nicknameInput = css` + width: 100%; + border: 0; + + background-color: ${Theme.color.gray200}; + outline: none; +`; diff --git a/frontend/src/pages/NicknamePage/NicknamePage.tsx b/frontend/src/pages/NicknamePage/NicknamePage.tsx index 3452bbbc..176bcde8 100644 --- a/frontend/src/pages/NicknamePage/NicknamePage.tsx +++ b/frontend/src/pages/NicknamePage/NicknamePage.tsx @@ -1,7 +1,17 @@ -import React from 'react'; +import { profile, nickname, nicknameInputWrapper, nicknameInput } from './NicknamePage.styled'; + +import Content from '@/components/layout/Content/Content'; const NicknamePage = () => { - return
this is Nick name page
; + return ( + +
+
닉네임
+
+ +
+
+ ); }; export default NicknamePage; From 0494eddb89def548c7188b906cb71fb74c0cf291 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Tue, 23 Jul 2024 19:13:49 +0900 Subject: [PATCH 0204/1013] =?UTF-8?q?feat:=20=EB=9E=9C=EB=8D=A4=20?= =?UTF-8?q?=EB=8B=89=EB=84=A4=EC=9E=84=20=EC=83=9D=EC=84=B1=20#46?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/NicknamePage/NicknamePage.tsx | 5 ++++- frontend/src/utils/.gitkeep | 0 frontend/src/utils/nickname.ts | 9 +++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) delete mode 100644 frontend/src/utils/.gitkeep create mode 100644 frontend/src/utils/nickname.ts diff --git a/frontend/src/pages/NicknamePage/NicknamePage.tsx b/frontend/src/pages/NicknamePage/NicknamePage.tsx index 176bcde8..0647c79b 100644 --- a/frontend/src/pages/NicknamePage/NicknamePage.tsx +++ b/frontend/src/pages/NicknamePage/NicknamePage.tsx @@ -1,14 +1,17 @@ import { profile, nickname, nicknameInputWrapper, nicknameInput } from './NicknamePage.styled'; import Content from '@/components/layout/Content/Content'; +import { createRandomNickname } from '@/utils/nickname'; const NicknamePage = () => { + const randomNickname = createRandomNickname(); + return (
닉네임
- +
); diff --git a/frontend/src/utils/.gitkeep b/frontend/src/utils/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/frontend/src/utils/nickname.ts b/frontend/src/utils/nickname.ts new file mode 100644 index 00000000..6314362b --- /dev/null +++ b/frontend/src/utils/nickname.ts @@ -0,0 +1,9 @@ +export const createRandomNickname = () => { + const adjectives = ['배고픈', '성실한', '욕망의', '섹시한', '멋있는', '타락한']; + const nouns = ['마루', '썬데이', '프린', '이든', '포메', '타칸', '커찬']; + + const randomAdjective = adjectives[Math.floor(Math.random() * adjectives.length)]; + const randomNoun = nouns[Math.floor(Math.random() * nouns.length)]; + + return `${randomAdjective} ${randomNoun}`; +}; From b54dee50dbc204da6f92e12dafa3a2bfd95bd3bd Mon Sep 17 00:00:00 2001 From: novice0840 Date: Wed, 24 Jul 2024 14:09:17 +0900 Subject: [PATCH 0205/1013] =?UTF-8?q?fix:=20=ED=83=9C=EA=B7=B8=EB=AA=85=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20#46?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/MainPage/MainPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/MainPage/MainPage.tsx b/frontend/src/pages/MainPage/MainPage.tsx index fac7ea5b..2be7aad3 100644 --- a/frontend/src/pages/MainPage/MainPage.tsx +++ b/frontend/src/pages/MainPage/MainPage.tsx @@ -15,7 +15,7 @@ const MainPage = () => {
LO to the GO

땅콩

-
어색한 분위기를 주도해봐요
+

어색한 분위기를 주도해봐요

); From 3b091cd4b1bdf6b9b2cbdb4d02b4a831f35edf5d Mon Sep 17 00:00:00 2001 From: novice0840 Date: Wed, 24 Jul 2024 14:30:46 +0900 Subject: [PATCH 0206/1013] =?UTF-8?q?fix:=20=EB=9E=9C=EB=8D=A4=20=EB=8B=89?= =?UTF-8?q?=EB=84=A4=EC=9E=84=20=EC=83=9D=EC=84=B1=20=ED=98=95=EC=9A=A9?= =?UTF-8?q?=EC=82=AC=20=EC=B6=94=EA=B0=80=20#46?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/utils/nickname.ts | 39 +++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/frontend/src/utils/nickname.ts b/frontend/src/utils/nickname.ts index 6314362b..d37ef2e3 100644 --- a/frontend/src/utils/nickname.ts +++ b/frontend/src/utils/nickname.ts @@ -1,5 +1,42 @@ export const createRandomNickname = () => { - const adjectives = ['배고픈', '성실한', '욕망의', '섹시한', '멋있는', '타락한']; + const adjectives = [ + '춤추는', + '노래하는', + '웃긴', + '귀여운', + '사랑스러운', + '재치있는', + '기운찬', + '활발한', + '지적인', + '영리한', + '장난꾸러기', + '유쾌한', + '깔끔한', + '매력적인', + '화려한', + '신나는', + '용감한', + '상냥한', + '달콤한', + '기발한', + '짜릿한', + '다정한', + '평온한', + '쾌활한', + '따뜻한', + '호기심 많은', + '재빠른', + '천재적인', + '엉뚱한', + '호탕한', + '멋진', + '섹시한', + '발랄한', + '당당한', + '명랑한', + '흥미로운', + ]; const nouns = ['마루', '썬데이', '프린', '이든', '포메', '타칸', '커찬']; const randomAdjective = adjectives[Math.floor(Math.random() * adjectives.length)]; From 3c79b99bda6c77c06f7b4a2d44d0815d69f96e95 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Wed, 24 Jul 2024 14:42:50 +0900 Subject: [PATCH 0207/1013] =?UTF-8?q?fix:=20=EB=9D=BC=EC=9A=B0=ED=8A=B8=20?= =?UTF-8?q?roundId=20=EC=A0=9C=EA=B1=B0=20#46?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/router/index.tsx | 4 ++-- frontend/src/utils/nickname.ts | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/frontend/src/router/index.tsx b/frontend/src/router/index.tsx index fd3bae91..02cb7b7d 100644 --- a/frontend/src/router/index.tsx +++ b/frontend/src/router/index.tsx @@ -26,11 +26,11 @@ export const router = createBrowserRouter([ element:
게임 대기 화면
, }, { - path: 'game/:roundId', + path: 'game', element: , }, { - path: 'round/:roundId/result', + path: 'round/result', element: , }, { diff --git a/frontend/src/utils/nickname.ts b/frontend/src/utils/nickname.ts index d37ef2e3..da1525f8 100644 --- a/frontend/src/utils/nickname.ts +++ b/frontend/src/utils/nickname.ts @@ -37,7 +37,38 @@ export const createRandomNickname = () => { '명랑한', '흥미로운', ]; - const nouns = ['마루', '썬데이', '프린', '이든', '포메', '타칸', '커찬']; + const nouns = [ + '강아지', + '고양이', + '개구리', + '딱다구리', + '사자', + '호랑이', + '코끼리', + '기린', + '고래', + '판다', + '토끼', + '햄스터', + '다람쥐', + '수달', + '원숭이', + '여우', + '늑대', + '말', + '돼지', + '소', + '양', + '염소', + '치타', + '타조', + '참새', + '비둘기', + '까마귀', + '공룡', + '거북이', + '독수리', + ]; const randomAdjective = adjectives[Math.floor(Math.random() * adjectives.length)]; const randomNoun = nouns[Math.floor(Math.random() * nouns.length)]; From 9c183a1c81c2806177e49f3f9535d2f0e3960959 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Wed, 24 Jul 2024 14:45:19 +0900 Subject: [PATCH 0208/1013] =?UTF-8?q?fix:=20css=20=EC=B5=9C=EC=86=8C=20?= =?UTF-8?q?=EB=8B=A8=EC=9C=84=20=ED=86=B5=EC=9D=BC=ED=99=94=20#46?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/NicknameList/NicknameList.styled.ts | 4 ++-- .../src/components/RoundVoteResult/RoundVoteResult.styled.ts | 4 ++-- .../src/components/SelectContainer/SelectContainer.styled.ts | 2 +- frontend/src/components/SelectOption/SelectOption.styled.ts | 2 +- .../src/components/TopicContainer/TopicContainer.styled.ts | 2 +- frontend/src/components/layout/Header/Header.styled.ts | 2 +- frontend/src/pages/NicknamePage/NicknamePage.styled.ts | 2 +- frontend/src/pages/RoundResultPage/RoundResultPage.styled.ts | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/frontend/src/components/NicknameList/NicknameList.styled.ts b/frontend/src/components/NicknameList/NicknameList.styled.ts index 655571f4..28f20d46 100644 --- a/frontend/src/components/NicknameList/NicknameList.styled.ts +++ b/frontend/src/components/NicknameList/NicknameList.styled.ts @@ -3,8 +3,8 @@ import { css } from '@emotion/react'; export const nicknameListLayout = css` display: flex; justify-content: space-around; - width: 24.5rem; - height: 15.4rem; + width: 24.4rem; + height: 15.8rem; `; export const nicknameContainer = css` diff --git a/frontend/src/components/RoundVoteResult/RoundVoteResult.styled.ts b/frontend/src/components/RoundVoteResult/RoundVoteResult.styled.ts index 32addcad..670869b9 100644 --- a/frontend/src/components/RoundVoteResult/RoundVoteResult.styled.ts +++ b/frontend/src/components/RoundVoteResult/RoundVoteResult.styled.ts @@ -10,8 +10,8 @@ export const roundVoteResultLayout = ({ percentage }: RoundVoteResultLayoutProps display: flex; justify-content: space-around; align-items: center; - width: 24.5rem; - height: 11rem; + width: 24rem; + height: 11.6rem; font-size: 1.2rem; background: linear-gradient( diff --git a/frontend/src/components/SelectContainer/SelectContainer.styled.ts b/frontend/src/components/SelectContainer/SelectContainer.styled.ts index f2c0a4d9..1a134def 100644 --- a/frontend/src/components/SelectContainer/SelectContainer.styled.ts +++ b/frontend/src/components/SelectContainer/SelectContainer.styled.ts @@ -5,7 +5,7 @@ export const selectContainerLayout = css` flex-direction: column; justify-content: center; align-items: center; - gap: 5rem; + gap: 4rem; flex-basis: 55%; `; diff --git a/frontend/src/components/SelectOption/SelectOption.styled.ts b/frontend/src/components/SelectOption/SelectOption.styled.ts index d7a5fa52..c5b03e0a 100644 --- a/frontend/src/components/SelectOption/SelectOption.styled.ts +++ b/frontend/src/components/SelectOption/SelectOption.styled.ts @@ -6,7 +6,7 @@ export const SelectOptionLayout = (selected: boolean) => css` display: flex; justify-content: center; align-items: center; - width: 11.4rem; + width: 11.6rem; height: 16.8rem; padding: 1.6rem; diff --git a/frontend/src/components/TopicContainer/TopicContainer.styled.ts b/frontend/src/components/TopicContainer/TopicContainer.styled.ts index 5d5cb40b..5906fc9e 100644 --- a/frontend/src/components/TopicContainer/TopicContainer.styled.ts +++ b/frontend/src/components/TopicContainer/TopicContainer.styled.ts @@ -11,7 +11,7 @@ export const topicContainerLayout = css` export const categoryText = css` font-weight: bold; - font-size: 1.4rem; + font-size: 1.2rem; `; export const topicText = css` diff --git a/frontend/src/components/layout/Header/Header.styled.ts b/frontend/src/components/layout/Header/Header.styled.ts index f9ca2b6b..0e19358f 100644 --- a/frontend/src/components/layout/Header/Header.styled.ts +++ b/frontend/src/components/layout/Header/Header.styled.ts @@ -4,7 +4,7 @@ export const headerLayout = css` display: flex; justify-content: space-between; align-items: center; - height: 7rem; + height: 8rem; `; export const gameTitle = css` diff --git a/frontend/src/pages/NicknamePage/NicknamePage.styled.ts b/frontend/src/pages/NicknamePage/NicknamePage.styled.ts index f2ad784c..7f9fd3a5 100644 --- a/frontend/src/pages/NicknamePage/NicknamePage.styled.ts +++ b/frontend/src/pages/NicknamePage/NicknamePage.styled.ts @@ -23,7 +23,7 @@ export const nicknameInputWrapper = css` display: flex; align-items: center; width: 26.8rem; - height: 4.9rem; + height: 4.8rem; padding: 0 1rem; background-color: ${Theme.color.gray200}; diff --git a/frontend/src/pages/RoundResultPage/RoundResultPage.styled.ts b/frontend/src/pages/RoundResultPage/RoundResultPage.styled.ts index 8425470f..410f844f 100644 --- a/frontend/src/pages/RoundResultPage/RoundResultPage.styled.ts +++ b/frontend/src/pages/RoundResultPage/RoundResultPage.styled.ts @@ -2,5 +2,5 @@ import { css } from '@emotion/react'; export const NicknameListWrapper = css` margin-top: 1.6rem; - margin-bottom: 0.7rem; + margin-bottom: 0.8rem; `; From 786dd27d7c8852763ea4abd67852cfc60154c139 Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 24 Jul 2024 15:55:23 +0900 Subject: [PATCH 0209/1013] =?UTF-8?q?chore:=20push=EC=8B=9C=20rebase?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EC=84=A4=EC=A0=95=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?#49?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.husky/pre-push | 49 ---------------------------------------- 1 file changed, 49 deletions(-) delete mode 100644 frontend/.husky/pre-push diff --git a/frontend/.husky/pre-push b/frontend/.husky/pre-push deleted file mode 100644 index 60e40380..00000000 --- a/frontend/.husky/pre-push +++ /dev/null @@ -1,49 +0,0 @@ -# cd frontend && npm run build-dev - - - -# 현재 브랜치 이름 가져오기 -current_branch=$(git rev-parse --abbrev-ref HEAD) - - -# 브랜치 패턴을 변수로 선언 -branch_patterns=("feat/" "hotfix/" "fix/" "refactor/" "test/") - -# 브랜치가 패턴에 맞는지 확인하는 함수 -matches_pattern() { - local branch=$1 - for pattern in "${branch_patterns[@]}"; do - if [[ $branch == $pattern* ]]; then - return 0 - fi - done - return 1 -} - -# feat/ 로 시작하는 브랜치인지 확인 -if matches_pattern "$current_branch"; then - echo "Feature branch detected: $current_branch" - echo "Starting rebase process..." - - # develop 브랜치로 전환 및 최신 변경사항 가져오기 - git checkout develop - git pull origin develop - - # 원래 브랜치로 돌아가기 - git checkout $current_branch - - # rebase 수행 - if git rebase develop; then - echo "Rebase completed successfully." - echo "Push completed." - exit 0 - else - echo "Rebase failed. Please resolve conflicts manually." - echo "After resolving conflicts, run:" - - exit 1 - fi -else - echo "Not a feature branch. Proceeding with normal push." - exit 0 -fi From 2f7c6b34732763ee13a56c0bd7aad45fef439a7a Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 24 Jul 2024 16:07:54 +0900 Subject: [PATCH 0210/1013] =?UTF-8?q?refactor:=20=EB=A7=A4=EA=B0=9C?= =?UTF-8?q?=EB=B3=80=EC=88=98=EC=9D=98=20=EC=84=A0=ED=83=9D=EC=A0=81=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EC=84=A0=EC=96=B8=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EA=B0=9C=EC=84=A0=20#49?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/common/Button/Button.styled.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/common/Button/Button.styled.ts b/frontend/src/components/common/Button/Button.styled.ts index 2fb9b08f..c235c879 100644 --- a/frontend/src/components/common/Button/Button.styled.ts +++ b/frontend/src/components/common/Button/Button.styled.ts @@ -9,7 +9,7 @@ interface ButtonLayoutProps { fontSize?: 'small' | 'medium' | 'large'; } -const getSizeStyles = (size: 'small' | 'medium' | 'large' | undefined) => { +const getSizeStyles = (size?: 'small' | 'medium' | 'large') => { switch (size) { case 'small': return css` @@ -34,7 +34,7 @@ const getSizeStyles = (size: 'small' | 'medium' | 'large' | undefined) => { } }; -const getFontSize = (fontSize: 'small' | 'medium' | 'large' | undefined) => { +const getFontSize = (fontSize?: 'small' | 'medium' | 'large') => { switch (fontSize) { case 'small': return Theme.typography.caption.fontSize; @@ -47,7 +47,7 @@ const getFontSize = (fontSize: 'small' | 'medium' | 'large' | undefined) => { } }; -const getBorderRadius = (radius: 'small' | 'medium' | 'large' | undefined) => { +const getBorderRadius = (radius?: 'small' | 'medium' | 'large') => { switch (radius) { case 'small': return Theme.borderRadius.radius10; From 52ef8e4f3dc2a661cea695f55eb2d275297d435c Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 24 Jul 2024 16:20:16 +0900 Subject: [PATCH 0211/1013] =?UTF-8?q?refactor:=20=EC=8A=A4=ED=83=80?= =?UTF-8?q?=EC=9D=BC=20=EC=9C=A0=ED=8B=B8=EB=A6=AC=ED=8B=B0=20=ED=95=A8?= =?UTF-8?q?=EC=88=98(getSizeStyles,=20getFontSize,=20getBorderRadius)?= =?UTF-8?q?=EB=93=A4=EC=9D=84=20=EB=B3=84=EB=8F=84=20=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B6=84=EB=A6=AC=20#49?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/common/Button/Button.styled.ts | 54 ++----------------- frontend/src/styles/utils/getBorderRadius.ts | 16 ++++++ frontend/src/styles/utils/getFontSize.ts | 16 ++++++ frontend/src/styles/utils/getSizeStyles.ts | 28 ++++++++++ 4 files changed, 63 insertions(+), 51 deletions(-) create mode 100644 frontend/src/styles/utils/getBorderRadius.ts create mode 100644 frontend/src/styles/utils/getFontSize.ts create mode 100644 frontend/src/styles/utils/getSizeStyles.ts diff --git a/frontend/src/components/common/Button/Button.styled.ts b/frontend/src/components/common/Button/Button.styled.ts index c235c879..f91662fe 100644 --- a/frontend/src/components/common/Button/Button.styled.ts +++ b/frontend/src/components/common/Button/Button.styled.ts @@ -1,6 +1,9 @@ import { css } from '@emotion/react'; import { Theme } from '@/styles/Theme'; +import getBorderRadius from '@/styles/utils/getBorderRadius'; +import getFontSize from '@/styles/utils/getFontSize'; +import getSizeStyles from '@/styles/utils/getSizeStyles'; interface ButtonLayoutProps { disabled?: boolean; @@ -9,57 +12,6 @@ interface ButtonLayoutProps { fontSize?: 'small' | 'medium' | 'large'; } -const getSizeStyles = (size?: 'small' | 'medium' | 'large') => { - switch (size) { - case 'small': - return css` - width: 6.8rem; - padding: 0.8rem 0; - `; - case 'medium': - return css` - width: 12rem; - padding: 1.6rem 0; - `; - case 'large': - return css` - width: 32rem; - padding: 2rem 0; - `; - default: - return css` - width: 32rem; - padding: 2rem 0; - `; - } -}; - -const getFontSize = (fontSize?: 'small' | 'medium' | 'large') => { - switch (fontSize) { - case 'small': - return Theme.typography.caption.fontSize; - case 'medium': - return Theme.typography.headline2.fontSize; - case 'large': - return Theme.typography.headline1.fontSize; - default: - return Theme.typography.headline2.fontSize; - } -}; - -const getBorderRadius = (radius?: 'small' | 'medium' | 'large') => { - switch (radius) { - case 'small': - return Theme.borderRadius.radius10; - case 'medium': - return Theme.borderRadius.radius20; - case 'large': - return Theme.borderRadius.radius30; - default: - return '0'; - } -}; - export const buttonLayout = ({ disabled, size, radius, fontSize }: ButtonLayoutProps) => css` display: flex; justify-content: center; diff --git a/frontend/src/styles/utils/getBorderRadius.ts b/frontend/src/styles/utils/getBorderRadius.ts new file mode 100644 index 00000000..993811cf --- /dev/null +++ b/frontend/src/styles/utils/getBorderRadius.ts @@ -0,0 +1,16 @@ +import { Theme } from '@/styles/Theme'; + +const getBorderRadius = (radius?: 'small' | 'medium' | 'large') => { + switch (radius) { + case 'small': + return Theme.borderRadius.radius10; + case 'medium': + return Theme.borderRadius.radius20; + case 'large': + return Theme.borderRadius.radius30; + default: + return '0'; + } +}; + +export default getBorderRadius; diff --git a/frontend/src/styles/utils/getFontSize.ts b/frontend/src/styles/utils/getFontSize.ts new file mode 100644 index 00000000..67a3e74b --- /dev/null +++ b/frontend/src/styles/utils/getFontSize.ts @@ -0,0 +1,16 @@ +import { Theme } from '@/styles/Theme'; + +const getFontSize = (fontSize?: 'small' | 'medium' | 'large') => { + switch (fontSize) { + case 'small': + return Theme.typography.caption.fontSize; + case 'medium': + return Theme.typography.headline2.fontSize; + case 'large': + return Theme.typography.headline1.fontSize; + default: + return Theme.typography.headline2.fontSize; + } +}; + +export default getFontSize; diff --git a/frontend/src/styles/utils/getSizeStyles.ts b/frontend/src/styles/utils/getSizeStyles.ts new file mode 100644 index 00000000..2ae4bf49 --- /dev/null +++ b/frontend/src/styles/utils/getSizeStyles.ts @@ -0,0 +1,28 @@ +import { css } from '@emotion/react'; + +const getSizeStyles = (size?: 'small' | 'medium' | 'large') => { + switch (size) { + case 'small': + return css` + width: 6.8rem; + padding: 0.8rem 0; + `; + case 'medium': + return css` + width: 12rem; + padding: 1.6rem 0; + `; + case 'large': + return css` + width: 32rem; + padding: 2rem 0; + `; + default: + return css` + width: 32rem; + padding: 2rem 0; + `; + } +}; + +export default getSizeStyles; From 4a88a4884eff79c8db097fb2d1a17c0cb37545dc Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 24 Jul 2024 17:37:22 +0900 Subject: [PATCH 0212/1013] =?UTF-8?q?merge:=20develop=20=EB=B8=8C=EB=9E=9C?= =?UTF-8?q?=EC=B9=98=20=EC=B6=A9=EB=8F=8C=20=EC=A0=9C=EA=B1=B0=20#49?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/dto/BalanceContentResponse.java | 14 ++-- .../exception/GlobalExceptionHandler.java | 8 +- .../domain/balance/content/Room.java | 10 +++ .../domain/balance/content/RoomContent.java | 20 +++++ .../content/RoomContentRepository.java | 2 +- .../balance/content/RoomRepository.java | 6 ++ .../exception/BadRequestException.java | 8 ++ .../exception/InternalServerException.java | 8 ++ .../content/BalanceContentService.java | 26 ++++--- .../excpetion/BusinessLogicException.java | 8 -- .../excpetion/ViolateDataException.java | 8 -- .../content/BalanceContentControllerTest.java | 2 +- .../content/RoomContentRepositoryTest.java | 11 ++- .../content/BalanceContentServiceTest.java | 32 +++++--- backend/src/test/resources/init-test.sql | 10 +-- frontend/.husky/prepare-commit-msg | 4 +- .../GameResult/GameResult.styled.ts | 2 +- .../src/components/GameResult/GameResult.tsx | 4 +- .../NicknameList/NicknameList.styled.ts | 6 +- .../components/NicknameList/NicknameList.tsx | 4 +- .../RoundVoteResult/RoundVoteResult.styled.ts | 8 +- .../RoundVoteResult/RoundVoteResult.tsx | 4 +- .../SelectContainer/SelectContainer.styled.ts | 4 +- .../SelectContainer/SelectContainer.tsx | 4 +- .../SelectOption/SelectOption.styled.ts | 4 +- .../components/SelectOption/SelectOption.tsx | 4 +- frontend/src/components/Timer/Timer.styled.ts | 2 +- frontend/src/components/Timer/Timer.tsx | 4 +- .../TopicContainer/TopicContainer.styled.ts | 4 +- .../TopicContainer/TopicContainer.tsx | 4 +- .../layout/Content/Content.styled.ts | 2 +- .../src/components/layout/Content/Content.tsx | 4 +- .../components/layout/Header/Header.styled.ts | 1 + .../src/pages/MainPage/MainPage.styled.ts | 30 ++++++++ frontend/src/pages/MainPage/MainPage.tsx | 24 ++++++ .../pages/NicknamePage/NicknamePage.styled.ts | 39 ++++++++++ .../src/pages/NicknamePage/NicknamePage.tsx | 20 +++++ .../RoundResultPage/RoundResultPage.styled.ts | 2 +- frontend/src/router/index.tsx | 20 ++++- frontend/src/styles/GlobalStyle.ts | 1 - frontend/src/styles/Theme.ts | 6 ++ frontend/src/utils/.gitkeep | 0 frontend/src/utils/nickname.ts | 77 +++++++++++++++++++ 43 files changed, 365 insertions(+), 96 deletions(-) create mode 100644 backend/src/main/java/ddangkong/domain/balance/content/RoomRepository.java create mode 100644 backend/src/main/java/ddangkong/exception/BadRequestException.java create mode 100644 backend/src/main/java/ddangkong/exception/InternalServerException.java delete mode 100644 backend/src/main/java/ddangkong/service/excpetion/BusinessLogicException.java delete mode 100644 backend/src/main/java/ddangkong/service/excpetion/ViolateDataException.java create mode 100644 frontend/src/pages/MainPage/MainPage.styled.ts create mode 100644 frontend/src/pages/MainPage/MainPage.tsx create mode 100644 frontend/src/pages/NicknamePage/NicknamePage.styled.ts create mode 100644 frontend/src/pages/NicknamePage/NicknamePage.tsx delete mode 100644 frontend/src/utils/.gitkeep create mode 100644 frontend/src/utils/nickname.ts diff --git a/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentResponse.java b/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentResponse.java index 66543da9..9f56359b 100644 --- a/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentResponse.java +++ b/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentResponse.java @@ -1,26 +1,30 @@ package ddangkong.controller.balance.content.dto; import ddangkong.controller.balance.option.dto.BalanceOptionResponse; -import ddangkong.domain.balance.content.BalanceContent; import ddangkong.domain.balance.content.Category; +import ddangkong.domain.balance.content.RoomContent; import ddangkong.domain.balance.option.BalanceOption; import lombok.Builder; public record BalanceContentResponse( Long contentId, Category category, + int totalRound, + int currentRound, String question, BalanceOptionResponse firstOption, BalanceOptionResponse secondOption ) { @Builder - private BalanceContentResponse(BalanceContent balanceContent, + private BalanceContentResponse(RoomContent roomContent, BalanceOption firstOption, BalanceOption secondOption) { - this(balanceContent.getId(), - balanceContent.getCategory(), - balanceContent.getName(), + this(roomContent.getContentId(), + roomContent.getContentCategory(), + roomContent.getTotalRound(), + roomContent.getRound(), + roomContent.getContentName(), BalanceOptionResponse.from(firstOption), BalanceOptionResponse.from(secondOption)); } diff --git a/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java b/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java index 1814c07e..382fd267 100644 --- a/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java +++ b/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java @@ -1,7 +1,7 @@ package ddangkong.controller.exception; -import ddangkong.service.excpetion.BusinessLogicException; -import ddangkong.service.excpetion.ViolateDataException; +import ddangkong.exception.BadRequestException; +import ddangkong.exception.InternalServerException; import jakarta.validation.ConstraintViolationException; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; @@ -34,7 +34,7 @@ public ErrorResponse handleConstraintViolationException(ConstraintViolationExcep @ExceptionHandler @ResponseStatus(HttpStatus.BAD_REQUEST) - public ErrorResponse handleBusinessLogicException(BusinessLogicException e) { + public ErrorResponse handleBadRequestException(BadRequestException e) { log.warn(e.getMessage()); return new ErrorResponse(e.getMessage()); @@ -42,7 +42,7 @@ public ErrorResponse handleBusinessLogicException(BusinessLogicException e) { @ExceptionHandler @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) - public ErrorResponse handleViolateDataException(ViolateDataException e) { + public ErrorResponse handleInternalServerErrorException(InternalServerException e) { log.error(e.getMessage(), e); return new ErrorResponse(SERVER_ERROR_MESSAGE); diff --git a/backend/src/main/java/ddangkong/domain/balance/content/Room.java b/backend/src/main/java/ddangkong/domain/balance/content/Room.java index 7dd029e8..f6d22153 100644 --- a/backend/src/main/java/ddangkong/domain/balance/content/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/content/Room.java @@ -1,5 +1,6 @@ package ddangkong.domain.balance.content; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; @@ -13,7 +14,16 @@ @Getter public class Room { + private static final int DEFAULT_TOTAL_ROUND = 5; + private static final int DEFAULT_CURRENT_ROUND = 1; + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + + @Column(nullable = false) + private int totalRound = DEFAULT_TOTAL_ROUND; + + @Column(nullable = false) + private int currentRound = DEFAULT_CURRENT_ROUND; } diff --git a/backend/src/main/java/ddangkong/domain/balance/content/RoomContent.java b/backend/src/main/java/ddangkong/domain/balance/content/RoomContent.java index 3f99b1f8..dc04a760 100644 --- a/backend/src/main/java/ddangkong/domain/balance/content/RoomContent.java +++ b/backend/src/main/java/ddangkong/domain/balance/content/RoomContent.java @@ -1,6 +1,7 @@ package ddangkong.domain.balance.content; import ddangkong.domain.BaseEntity; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; @@ -28,4 +29,23 @@ public class RoomContent extends BaseEntity { @ManyToOne(optional = false, fetch = FetchType.LAZY) @JoinColumn(name = "balance_content_id") private BalanceContent balanceContent; + + @Column(nullable = false) + private int round; + + public Long getContentId() { + return balanceContent.getId(); + } + + public Category getContentCategory() { + return balanceContent.getCategory(); + } + + public String getContentName() { + return balanceContent.getName(); + } + + public int getTotalRound() { + return room.getTotalRound(); + } } diff --git a/backend/src/main/java/ddangkong/domain/balance/content/RoomContentRepository.java b/backend/src/main/java/ddangkong/domain/balance/content/RoomContentRepository.java index ea9f4ce2..d27a04dd 100644 --- a/backend/src/main/java/ddangkong/domain/balance/content/RoomContentRepository.java +++ b/backend/src/main/java/ddangkong/domain/balance/content/RoomContentRepository.java @@ -5,5 +5,5 @@ public interface RoomContentRepository extends JpaRepository { - Optional findTopByRoomIdOrderByCreatedAtDesc(Long roomId); + Optional findByRoomAndRound(Room room, int round); } diff --git a/backend/src/main/java/ddangkong/domain/balance/content/RoomRepository.java b/backend/src/main/java/ddangkong/domain/balance/content/RoomRepository.java new file mode 100644 index 00000000..e9b0759e --- /dev/null +++ b/backend/src/main/java/ddangkong/domain/balance/content/RoomRepository.java @@ -0,0 +1,6 @@ +package ddangkong.domain.balance.content; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface RoomRepository extends JpaRepository { +} diff --git a/backend/src/main/java/ddangkong/exception/BadRequestException.java b/backend/src/main/java/ddangkong/exception/BadRequestException.java new file mode 100644 index 00000000..39849d34 --- /dev/null +++ b/backend/src/main/java/ddangkong/exception/BadRequestException.java @@ -0,0 +1,8 @@ +package ddangkong.exception; + +public class BadRequestException extends RuntimeException { + + public BadRequestException(String message) { + super(message); + } +} diff --git a/backend/src/main/java/ddangkong/exception/InternalServerException.java b/backend/src/main/java/ddangkong/exception/InternalServerException.java new file mode 100644 index 00000000..43f60da4 --- /dev/null +++ b/backend/src/main/java/ddangkong/exception/InternalServerException.java @@ -0,0 +1,8 @@ +package ddangkong.exception; + +public class InternalServerException extends RuntimeException { + + public InternalServerException(String message) { + super(message); + } +} diff --git a/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java b/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java index a3a4b611..775a2937 100644 --- a/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java +++ b/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java @@ -2,11 +2,14 @@ import ddangkong.controller.balance.content.dto.BalanceContentResponse; import ddangkong.domain.balance.content.BalanceContent; +import ddangkong.domain.balance.content.Room; +import ddangkong.domain.balance.content.RoomContent; import ddangkong.domain.balance.content.RoomContentRepository; +import ddangkong.domain.balance.content.RoomRepository; import ddangkong.domain.balance.option.BalanceOption; import ddangkong.domain.balance.option.BalanceOptionRepository; -import ddangkong.service.excpetion.BusinessLogicException; -import ddangkong.service.excpetion.ViolateDataException; +import ddangkong.exception.BadRequestException; +import ddangkong.exception.InternalServerException; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -18,26 +21,29 @@ public class BalanceContentService { private static final int BALANCE_OPTION_SIZE = 2; + private final RoomRepository roomRepository; + private final RoomContentRepository roomContentRepository; private final BalanceOptionRepository balanceOptionRepository; @Transactional(readOnly = true) public BalanceContentResponse findRecentBalanceContent(Long roomId) { - BalanceContent balanceContent = findRecentContent(roomId); - List balanceOptions = findBalanceOptions(balanceContent); + RoomContent roomContent = findCurrentRoomContent(roomId); + List balanceOptions = findBalanceOptions(roomContent.getBalanceContent()); return BalanceContentResponse.builder() - .balanceContent(balanceContent) + .roomContent(roomContent) .firstOption(balanceOptions.get(0)) .secondOption(balanceOptions.get(1)) .build(); } - private BalanceContent findRecentContent(Long roomId) { - return roomContentRepository.findTopByRoomIdOrderByCreatedAtDesc(roomId) - .orElseThrow(() -> new BusinessLogicException("해당 방의 질문이 존재하지 않습니다.")) - .getBalanceContent(); + private RoomContent findCurrentRoomContent(Long roomId) { + Room room = roomRepository.findById(roomId) + .orElseThrow(() -> new BadRequestException("해당 방이 존재하지 않습니다.")); + return roomContentRepository.findByRoomAndRound(room, room.getCurrentRound()) + .orElseThrow(() -> new BadRequestException("해당 방의 현재 진행중인 질문이 존재하지 않습니다.")); } private List findBalanceOptions(BalanceContent balanceContent) { @@ -48,7 +54,7 @@ private List findBalanceOptions(BalanceContent balanceContent) { private void validateBalanceOptions(List balanceOptions) { if (balanceOptions.size() != BALANCE_OPTION_SIZE) { - throw new ViolateDataException("밸런스 게임의 선택지가 %d개입니다".formatted(balanceOptions.size())); + throw new InternalServerException("밸런스 게임의 선택지가 %d개입니다".formatted(balanceOptions.size())); } } } diff --git a/backend/src/main/java/ddangkong/service/excpetion/BusinessLogicException.java b/backend/src/main/java/ddangkong/service/excpetion/BusinessLogicException.java deleted file mode 100644 index d2b522cb..00000000 --- a/backend/src/main/java/ddangkong/service/excpetion/BusinessLogicException.java +++ /dev/null @@ -1,8 +0,0 @@ -package ddangkong.service.excpetion; - -public class BusinessLogicException extends RuntimeException { - - public BusinessLogicException(String message) { - super(message); - } -} diff --git a/backend/src/main/java/ddangkong/service/excpetion/ViolateDataException.java b/backend/src/main/java/ddangkong/service/excpetion/ViolateDataException.java deleted file mode 100644 index 48192f9b..00000000 --- a/backend/src/main/java/ddangkong/service/excpetion/ViolateDataException.java +++ /dev/null @@ -1,8 +0,0 @@ -package ddangkong.service.excpetion; - -public class ViolateDataException extends RuntimeException { - - public ViolateDataException(String message) { - super(message); - } -} diff --git a/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java index 67d24b7d..722b8d86 100644 --- a/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java @@ -16,7 +16,7 @@ class BalanceContentControllerTest extends BaseControllerTest { class 현재_방의_내용_조회 { private static final BalanceContentResponse EXPECTED_RESPONSE = new BalanceContentResponse( - 1L, Category.EXAMPLE, "민초 vs 반민초", + 1L, Category.EXAMPLE, 5, 2, "민초 vs 반민초", new BalanceOptionResponse(1L, "민초"), new BalanceOptionResponse(2L, "반민초")); diff --git a/backend/src/test/java/ddangkong/domain/balance/content/RoomContentRepositoryTest.java b/backend/src/test/java/ddangkong/domain/balance/content/RoomContentRepositoryTest.java index 91d270eb..067644f0 100644 --- a/backend/src/test/java/ddangkong/domain/balance/content/RoomContentRepositoryTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/content/RoomContentRepositoryTest.java @@ -12,16 +12,21 @@ class RoomContentRepositoryTest extends BaseRepositoryTest { @Autowired private RoomContentRepository roomContentRepository; + @Autowired + private RoomRepository roomRepository; + @Nested - class 방의_최신_질문_조회 { + class 방의_해당_라운드_질문_조회 { @Test - void 방의_가장_최신의_질문을_조회할_수_있다() { + void 방의_해당_라운드의_질문을_조회할_수_있다() { // given Long roomId = 1L; + Room room = roomRepository.findById(roomId).get(); + int round = 2; // when - RoomContent actual = roomContentRepository.findTopByRoomIdOrderByCreatedAtDesc(roomId).get(); + RoomContent actual = roomContentRepository.findByRoomAndRound(room, round).get(); // then assertThat(actual.getId()).isEqualTo(2L); diff --git a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java index fc87fda2..1845abc9 100644 --- a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java @@ -6,29 +6,29 @@ import ddangkong.controller.balance.content.dto.BalanceContentResponse; import ddangkong.controller.balance.option.dto.BalanceOptionResponse; import ddangkong.domain.balance.content.Category; +import ddangkong.exception.BadRequestException; import ddangkong.service.BaseServiceTest; -import ddangkong.service.excpetion.BusinessLogicException; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; class BalanceContentServiceTest extends BaseServiceTest { - private static final Long PROGRESS_ROOM_ID = 1L; - private static final Long NOT_EXIST_ROOM_ID = 2L; - private static final BalanceContentResponse BALANCE_CONTENT_RESPONSE = new BalanceContentResponse( - 1L, Category.EXAMPLE, "민초 vs 반민초", - new BalanceOptionResponse(1L, "민초"), - new BalanceOptionResponse(2L, "반민초")); - @Autowired private BalanceContentService balanceContentService; - @Nested class 현재_방의_밸런스_게임_내용_조회 { + private static final Long PROGRESS_ROOM_ID = 1L; + private static final Long NOT_EXIST_ROOM_ID = 3L; + private static final Long NOT_PROGRESSED_ROOM_ID = 2L; + private static final BalanceContentResponse BALANCE_CONTENT_RESPONSE = new BalanceContentResponse( + 1L, Category.EXAMPLE, 5, 2, "민초 vs 반민초", + new BalanceOptionResponse(1L, "민초"), + new BalanceOptionResponse(2L, "반민초")); + @Test - void 방의_최신_밸런스_게임_내용을_조회할_수_있다() { + void 방의_진행_중인_밸런스_게임_내용을_조회할_수_있다() { // when BalanceContentResponse actual = balanceContentService.findRecentBalanceContent(PROGRESS_ROOM_ID); @@ -40,8 +40,16 @@ class 현재_방의_밸런스_게임_내용_조회 { void 방이_없을_경우_예외를_던진다() { // when & then assertThatThrownBy(() -> balanceContentService.findRecentBalanceContent(NOT_EXIST_ROOM_ID)) - .isInstanceOf(BusinessLogicException.class) - .hasMessage("해당 방의 질문이 존재하지 않습니다."); + .isInstanceOf(BadRequestException.class) + .hasMessage("해당 방이 존재하지 않습니다."); + } + + @Test + void 방의_현재_라운드의_질문이_없을_경우_예외를_던진다() { + // when & then + assertThatThrownBy(() -> balanceContentService.findRecentBalanceContent(NOT_PROGRESSED_ROOM_ID)) + .isInstanceOf(BadRequestException.class) + .hasMessage("해당 방의 현재 진행중인 질문이 존재하지 않습니다."); } } } diff --git a/backend/src/test/resources/init-test.sql b/backend/src/test/resources/init-test.sql index a583b8f4..4f1cdee0 100644 --- a/backend/src/test/resources/init-test.sql +++ b/backend/src/test/resources/init-test.sql @@ -1,5 +1,5 @@ -INSERT INTO room () -VALUES (); +INSERT INTO room (total_round, current_round) +VALUES (5, 2), (5, 1); INSERT INTO member (nickname, room_id) VALUES ('mohamedeu al katan', 1), @@ -11,9 +11,9 @@ INSERT INTO balance_content (category, name) VALUES ('EXAMPLE', '민초 vs 반민초'), ('EXAMPLE', '월 200 백수 vs 월 500 직장인'); -INSERT INTO room_content (room_id, balance_content_id, created_at) -VALUES (1, 2, '2024-07-18 19:50:00.000'), - (1, 1, '2024-07-18 20:00:00.000'); +INSERT INTO room_content (room_id, balance_content_id, round, created_at) +VALUES (1, 2, 1, '2024-07-18 19:50:00.000'), + (1, 1, 2, '2024-07-18 20:00:00.000'); INSERT INTO balance_option (name, balance_content_id) VALUES ('민초', 1), diff --git a/frontend/.husky/prepare-commit-msg b/frontend/.husky/prepare-commit-msg index 0e6deab0..0e59ba2e 100644 --- a/frontend/.husky/prepare-commit-msg +++ b/frontend/.husky/prepare-commit-msg @@ -4,7 +4,7 @@ COMMIT_MSG_FILE=$1 COMMIT_MSG=$(cat $1) # 허용하는 commit prefix -ALLOWED_PREFIXES="^(feat|fix|refactor|build|docs|chore|test|style|design|init): " +ALLOWED_PREFIXES="^(feat|fix|refactor|build|docs|chore|test|style|design|init|merge): " # 현재 브랜치명 CURRENT_BRANCH=$(git branch --show-current) @@ -14,7 +14,7 @@ ISSUE_NUMBER=$(echo $CURRENT_BRANCH | sed -n 's/.*#\([0-9]*\).*/\1/p') if ! echo "$COMMIT_MSG" | grep -Eq "$ALLOWED_PREFIXES"; then echo "Error: Commit message does not follow the convention." - echo "Allowed prefixes: feat:, fix:, refactor:, build:, docs:, chore:, test:, style:, design:, init:" + echo "Allowed prefixes: feat:, fix:, refactor:, build:, docs:, chore:, test:, style:, design:, init:, merge:" exit 1 fi diff --git a/frontend/src/components/GameResult/GameResult.styled.ts b/frontend/src/components/GameResult/GameResult.styled.ts index 0dfd6cae..5b6951d5 100644 --- a/frontend/src/components/GameResult/GameResult.styled.ts +++ b/frontend/src/components/GameResult/GameResult.styled.ts @@ -1,6 +1,6 @@ import { css } from '@emotion/react'; -export const layout = css` +export const gameResultLayout = css` display: flex; flex-direction: column; justify-content: center; diff --git a/frontend/src/components/GameResult/GameResult.tsx b/frontend/src/components/GameResult/GameResult.tsx index a5d1067b..cb21e4ef 100644 --- a/frontend/src/components/GameResult/GameResult.tsx +++ b/frontend/src/components/GameResult/GameResult.tsx @@ -1,6 +1,6 @@ import { useNavigate } from 'react-router-dom'; -import { gameResultTitle, gameResultTitleWrapper, layout } from './GameResult.styled'; +import { gameResultTitle, gameResultTitleWrapper, gameResultLayout } from './GameResult.styled'; import Button from '@/components/common/Button/Button'; @@ -12,7 +12,7 @@ const GameResult = () => { }; return ( -
+

게임 결과

diff --git a/frontend/src/components/NicknameList/NicknameList.styled.ts b/frontend/src/components/NicknameList/NicknameList.styled.ts index d1fe809c..28f20d46 100644 --- a/frontend/src/components/NicknameList/NicknameList.styled.ts +++ b/frontend/src/components/NicknameList/NicknameList.styled.ts @@ -1,10 +1,10 @@ import { css } from '@emotion/react'; -export const layout = css` +export const nicknameListLayout = css` display: flex; justify-content: space-around; - width: 24.5rem; - height: 15.4rem; + width: 24.4rem; + height: 15.8rem; `; export const nicknameContainer = css` diff --git a/frontend/src/components/NicknameList/NicknameList.tsx b/frontend/src/components/NicknameList/NicknameList.tsx index a72d8c95..35f83aa0 100644 --- a/frontend/src/components/NicknameList/NicknameList.tsx +++ b/frontend/src/components/NicknameList/NicknameList.tsx @@ -1,11 +1,11 @@ -import { layout, nicknameContainer, verticalLine } from './NicknameList.styled'; +import { nicknameListLayout, nicknameContainer, verticalLine } from './NicknameList.styled'; const NicknameList = () => { const optionANicknames = ['철수', '철수', '철수', '철수', '철수', '철수', '철수', '철수', '철수']; const optionBNicknames = ['영미', '영미', '영미']; return ( -
+
{optionANicknames.map((optionANickname) => ( {optionANickname} diff --git a/frontend/src/components/RoundVoteResult/RoundVoteResult.styled.ts b/frontend/src/components/RoundVoteResult/RoundVoteResult.styled.ts index b99fb612..670869b9 100644 --- a/frontend/src/components/RoundVoteResult/RoundVoteResult.styled.ts +++ b/frontend/src/components/RoundVoteResult/RoundVoteResult.styled.ts @@ -2,16 +2,16 @@ import { css } from '@emotion/react'; import { Theme } from '@/styles/Theme'; -interface LayoutProps { +interface RoundVoteResultLayoutProps { percentage: number; } -export const layout = ({ percentage }: LayoutProps) => css` +export const roundVoteResultLayout = ({ percentage }: RoundVoteResultLayoutProps) => css` display: flex; justify-content: space-around; align-items: center; - width: 24.5rem; - height: 11rem; + width: 24rem; + height: 11.6rem; font-size: 1.2rem; background: linear-gradient( diff --git a/frontend/src/components/RoundVoteResult/RoundVoteResult.tsx b/frontend/src/components/RoundVoteResult/RoundVoteResult.tsx index a780a118..634ac52e 100644 --- a/frontend/src/components/RoundVoteResult/RoundVoteResult.tsx +++ b/frontend/src/components/RoundVoteResult/RoundVoteResult.tsx @@ -1,4 +1,4 @@ -import { layout, fontBold, voteContent } from './RoundVoteResult.styled'; +import { roundVoteResultLayout, fontBold, voteContent } from './RoundVoteResult.styled'; import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; @@ -6,7 +6,7 @@ const RoundVoteResult = () => { const { balanceContent } = useBalanceContentQuery(); return ( -
+
{balanceContent?.firstOption.name}
72%
diff --git a/frontend/src/components/SelectContainer/SelectContainer.styled.ts b/frontend/src/components/SelectContainer/SelectContainer.styled.ts index 80ba82c2..1a134def 100644 --- a/frontend/src/components/SelectContainer/SelectContainer.styled.ts +++ b/frontend/src/components/SelectContainer/SelectContainer.styled.ts @@ -1,11 +1,11 @@ import { css } from '@emotion/react'; -export const layout = css` +export const selectContainerLayout = css` display: flex; flex-direction: column; justify-content: center; align-items: center; - gap: 5rem; + gap: 4rem; flex-basis: 55%; `; diff --git a/frontend/src/components/SelectContainer/SelectContainer.tsx b/frontend/src/components/SelectContainer/SelectContainer.tsx index edc2e264..b5e96e09 100644 --- a/frontend/src/components/SelectContainer/SelectContainer.tsx +++ b/frontend/src/components/SelectContainer/SelectContainer.tsx @@ -1,7 +1,7 @@ import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; -import { layout, selectSection } from './SelectContainer.styled'; +import { selectContainerLayout, selectSection } from './SelectContainer.styled'; import Button from '@/components/common/Button/Button'; import SelectOption from '@/components/SelectOption/SelectOption'; @@ -25,7 +25,7 @@ const SelectContainer = () => { return ( <> {balanceContent && ( -
+
css` +export const SelectOptionLayout = (selected: boolean) => css` display: flex; justify-content: center; align-items: center; - width: 11.4rem; + width: 11.6rem; height: 16.8rem; padding: 1.6rem; diff --git a/frontend/src/components/SelectOption/SelectOption.tsx b/frontend/src/components/SelectOption/SelectOption.tsx index 4070eb93..cb7f7312 100644 --- a/frontend/src/components/SelectOption/SelectOption.tsx +++ b/frontend/src/components/SelectOption/SelectOption.tsx @@ -1,4 +1,4 @@ -import { layout } from './SelectOption.styled'; +import { SelectOptionLayout } from './SelectOption.styled'; import { BalanceContent } from '@/types/balanceContent'; @@ -11,7 +11,7 @@ interface SelectOptionProps { const SelectOption = ({ option, selectedId, handleSelectOption }: SelectOptionProps) => { return ( +
+ ); +}; + +export default MainPage; diff --git a/frontend/src/pages/NicknamePage/NicknamePage.styled.ts b/frontend/src/pages/NicknamePage/NicknamePage.styled.ts new file mode 100644 index 00000000..7f9fd3a5 --- /dev/null +++ b/frontend/src/pages/NicknamePage/NicknamePage.styled.ts @@ -0,0 +1,39 @@ +import { css } from '@emotion/react'; + +import { Theme } from '@/styles/Theme'; + +export const profile = css` + width: 8rem; + height: 8rem; + margin-top: 4rem; + + background-color: ${Theme.color.gray300}; + border-radius: 50%; +`; + +export const nickname = css` + width: 26.8rem; + margin: 2rem 0; + + font-weight: 600; + font-size: 1.6rem; +`; + +export const nicknameInputWrapper = css` + display: flex; + align-items: center; + width: 26.8rem; + height: 4.8rem; + padding: 0 1rem; + + background-color: ${Theme.color.gray200}; + border-radius: 1rem; +`; + +export const nicknameInput = css` + width: 100%; + border: 0; + + background-color: ${Theme.color.gray200}; + outline: none; +`; diff --git a/frontend/src/pages/NicknamePage/NicknamePage.tsx b/frontend/src/pages/NicknamePage/NicknamePage.tsx new file mode 100644 index 00000000..0647c79b --- /dev/null +++ b/frontend/src/pages/NicknamePage/NicknamePage.tsx @@ -0,0 +1,20 @@ +import { profile, nickname, nicknameInputWrapper, nicknameInput } from './NicknamePage.styled'; + +import Content from '@/components/layout/Content/Content'; +import { createRandomNickname } from '@/utils/nickname'; + +const NicknamePage = () => { + const randomNickname = createRandomNickname(); + + return ( + +
+
닉네임
+
+ +
+
+ ); +}; + +export default NicknamePage; diff --git a/frontend/src/pages/RoundResultPage/RoundResultPage.styled.ts b/frontend/src/pages/RoundResultPage/RoundResultPage.styled.ts index 8425470f..410f844f 100644 --- a/frontend/src/pages/RoundResultPage/RoundResultPage.styled.ts +++ b/frontend/src/pages/RoundResultPage/RoundResultPage.styled.ts @@ -2,5 +2,5 @@ import { css } from '@emotion/react'; export const NicknameListWrapper = css` margin-top: 1.6rem; - margin-bottom: 0.7rem; + margin-bottom: 0.8rem; `; diff --git a/frontend/src/router/index.tsx b/frontend/src/router/index.tsx index 056d3fe7..02cb7b7d 100644 --- a/frontend/src/router/index.tsx +++ b/frontend/src/router/index.tsx @@ -4,23 +4,37 @@ import { Layout } from './layout'; import GamePage from '@/pages/GamePage/GamePage'; import GameResultPage from '@/pages/GameResultPage/GameResultPage'; +import MainPage from '@/pages/MainPage/MainPage'; +import NicknamePage from '@/pages/NicknamePage/NicknamePage'; import RoundResultPage from '@/pages/RoundResultPage/RoundResultPage'; export const router = createBrowserRouter([ + { + path: '/', + element: , + }, { path: '/', element: , children: [ { - index: true, + path: 'nickname', + element: , + }, + { + path: 'ready', + element:
게임 대기 화면
, + }, + { + path: 'game', element: , }, { - path: 'round-result', + path: 'round/result', element: , }, { - path: 'game-result', + path: 'game/result', element: , }, ], diff --git a/frontend/src/styles/GlobalStyle.ts b/frontend/src/styles/GlobalStyle.ts index f3217262..7c8fe3ef 100644 --- a/frontend/src/styles/GlobalStyle.ts +++ b/frontend/src/styles/GlobalStyle.ts @@ -143,7 +143,6 @@ const GlobalStyle = css` ${reset} html { - margin-top: 3rem; font-size: 10px; } diff --git a/frontend/src/styles/Theme.ts b/frontend/src/styles/Theme.ts index 934d2d34..1d1ffb61 100644 --- a/frontend/src/styles/Theme.ts +++ b/frontend/src/styles/Theme.ts @@ -1,8 +1,14 @@ const color = { // primary color + peanut200: '#FFF0D4', peanut300: '#FFF4DF', peanut400: '#FFDD9A', peanut500: '#FFD076', + + gray200: '#F3F1F1', + gray300: '#E4E4E4', + gray400: '#9D9B9B', + gray500: '#7A7A7A', } as const; export const borderRadius = { diff --git a/frontend/src/utils/.gitkeep b/frontend/src/utils/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/frontend/src/utils/nickname.ts b/frontend/src/utils/nickname.ts new file mode 100644 index 00000000..da1525f8 --- /dev/null +++ b/frontend/src/utils/nickname.ts @@ -0,0 +1,77 @@ +export const createRandomNickname = () => { + const adjectives = [ + '춤추는', + '노래하는', + '웃긴', + '귀여운', + '사랑스러운', + '재치있는', + '기운찬', + '활발한', + '지적인', + '영리한', + '장난꾸러기', + '유쾌한', + '깔끔한', + '매력적인', + '화려한', + '신나는', + '용감한', + '상냥한', + '달콤한', + '기발한', + '짜릿한', + '다정한', + '평온한', + '쾌활한', + '따뜻한', + '호기심 많은', + '재빠른', + '천재적인', + '엉뚱한', + '호탕한', + '멋진', + '섹시한', + '발랄한', + '당당한', + '명랑한', + '흥미로운', + ]; + const nouns = [ + '강아지', + '고양이', + '개구리', + '딱다구리', + '사자', + '호랑이', + '코끼리', + '기린', + '고래', + '판다', + '토끼', + '햄스터', + '다람쥐', + '수달', + '원숭이', + '여우', + '늑대', + '말', + '돼지', + '소', + '양', + '염소', + '치타', + '타조', + '참새', + '비둘기', + '까마귀', + '공룡', + '거북이', + '독수리', + ]; + + const randomAdjective = adjectives[Math.floor(Math.random() * adjectives.length)]; + const randomNoun = nouns[Math.floor(Math.random() * nouns.length)]; + + return `${randomAdjective} ${randomNoun}`; +}; From d9046b60b365c01b696d73d0e93925279c1f766c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yuseon=20Kim=28=EC=8D=AC=EB=8D=B0=EC=9D=B4=29?= <74897720+useon@users.noreply.github.com> Date: Wed, 24 Jul 2024 17:52:20 +0900 Subject: [PATCH 0213/1013] =?UTF-8?q?refactor:=20=EB=B2=84=ED=8A=BC=20acti?= =?UTF-8?q?ve=20prop=20=EC=82=AD=EC=A0=9C=EC=97=90=20=EB=94=B0=EB=A5=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20#49?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/MainPage/MainPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/MainPage/MainPage.tsx b/frontend/src/pages/MainPage/MainPage.tsx index 2be7aad3..750de876 100644 --- a/frontend/src/pages/MainPage/MainPage.tsx +++ b/frontend/src/pages/MainPage/MainPage.tsx @@ -16,7 +16,7 @@ const MainPage = () => {
LO to the GO

땅콩

어색한 분위기를 주도해봐요

- +
); }; From b1cd2b2070d034f19066bf985c442b25c4cfe6aa Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 24 Jul 2024 18:17:38 +0900 Subject: [PATCH 0214/1013] =?UTF-8?q?feat:=20=ED=88=AC=ED=91=9C=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EA=B4=80=EB=A0=A8=20=EB=A0=88=ED=8F=AC?= =?UTF-8?q?=EC=A7=80=ED=86=A0=EB=A6=AC=20=EA=B5=AC=ED=98=84=20#15?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../balance/option/BalanceOptionRepository.java | 6 ++++++ .../domain/balance/vote/BalanceVoteRepository.java | 6 ++++++ .../ddangkong/domain/member/MemberRepository.java | 12 ++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 backend/src/main/java/ddangkong/domain/balance/vote/BalanceVoteRepository.java create mode 100644 backend/src/main/java/ddangkong/domain/member/MemberRepository.java diff --git a/backend/src/main/java/ddangkong/domain/balance/option/BalanceOptionRepository.java b/backend/src/main/java/ddangkong/domain/balance/option/BalanceOptionRepository.java index 10d886be..d30016c0 100644 --- a/backend/src/main/java/ddangkong/domain/balance/option/BalanceOptionRepository.java +++ b/backend/src/main/java/ddangkong/domain/balance/option/BalanceOptionRepository.java @@ -1,10 +1,16 @@ package ddangkong.domain.balance.option; import ddangkong.domain.balance.content.BalanceContent; +import ddangkong.exception.BadRequestException; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; public interface BalanceOptionRepository extends JpaRepository { List findByBalanceContent(BalanceContent balanceContent); + + default BalanceOption getById(Long id) { + return findById(id) + .orElseThrow(() -> new BadRequestException("해당 옵션이 존재하지 않습니다.")); + } } diff --git a/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVoteRepository.java b/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVoteRepository.java new file mode 100644 index 00000000..9e3d851f --- /dev/null +++ b/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVoteRepository.java @@ -0,0 +1,6 @@ +package ddangkong.domain.balance.vote; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface BalanceVoteRepository extends JpaRepository { +} diff --git a/backend/src/main/java/ddangkong/domain/member/MemberRepository.java b/backend/src/main/java/ddangkong/domain/member/MemberRepository.java new file mode 100644 index 00000000..742589f7 --- /dev/null +++ b/backend/src/main/java/ddangkong/domain/member/MemberRepository.java @@ -0,0 +1,12 @@ +package ddangkong.domain.member; + +import ddangkong.exception.BadRequestException; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MemberRepository extends JpaRepository { + + default Member getById(Long id) { + return findById(id) + .orElseThrow(() -> new BadRequestException("해당 멤버가 존재하지 않습니다.")); + } +} From 49a21bb2d50ab280b5e5284e029d364bf183f74a Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 24 Jul 2024 18:21:40 +0900 Subject: [PATCH 0215/1013] =?UTF-8?q?feat:=20=ED=95=84=EC=9A=94=ED=95=9C?= =?UTF-8?q?=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EB=A1=9C=EC=A7=81=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1=20#15?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/balance/content/Room.java | 4 ++ .../domain/balance/option/BalanceOption.java | 10 +++++ .../domain/balance/vote/BalanceVote.java | 9 ++++ .../java/ddangkong/domain/member/Member.java | 10 +++++ .../balance/option/BalanceOptionTest.java | 41 +++++++++++++++++++ .../ddangkong/domain/member/MemberTest.java | 37 +++++++++++++++++ 6 files changed, 111 insertions(+) create mode 100644 backend/src/test/java/ddangkong/domain/balance/option/BalanceOptionTest.java create mode 100644 backend/src/test/java/ddangkong/domain/member/MemberTest.java diff --git a/backend/src/main/java/ddangkong/domain/balance/content/Room.java b/backend/src/main/java/ddangkong/domain/balance/content/Room.java index f6d22153..3d9303ac 100644 --- a/backend/src/main/java/ddangkong/domain/balance/content/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/content/Room.java @@ -26,4 +26,8 @@ public class Room { @Column(nullable = false) private int currentRound = DEFAULT_CURRENT_ROUND; + + public Room(Long id) { + this.id = id; + } } diff --git a/backend/src/main/java/ddangkong/domain/balance/option/BalanceOption.java b/backend/src/main/java/ddangkong/domain/balance/option/BalanceOption.java index bc65918d..1147f47a 100644 --- a/backend/src/main/java/ddangkong/domain/balance/option/BalanceOption.java +++ b/backend/src/main/java/ddangkong/domain/balance/option/BalanceOption.java @@ -28,4 +28,14 @@ public class BalanceOption { @ManyToOne(optional = false, fetch = FetchType.LAZY) @JoinColumn(name = "balance_content_id", nullable = false) private BalanceContent balanceContent; + + public BalanceOption(Long id, String name, BalanceContent balanceContent) { + this.id = id; + this.name = name; + this.balanceContent = balanceContent; + } + + public boolean isNotContained(Long contentId) { + return !balanceContent.getId().equals(contentId); + } } diff --git a/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVote.java b/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVote.java index 981d3715..717a3634 100644 --- a/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVote.java +++ b/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVote.java @@ -29,4 +29,13 @@ public class BalanceVote { @ManyToOne(optional = false, fetch = FetchType.LAZY) @JoinColumn(name = "member_id", nullable = false) private Member member; + + public BalanceVote(BalanceOption balanceOption, Member member) { + this.balanceOption = balanceOption; + this.member = member; + } + + public Long getOptionId() { + return balanceOption.getId(); + } } diff --git a/backend/src/main/java/ddangkong/domain/member/Member.java b/backend/src/main/java/ddangkong/domain/member/Member.java index efedc670..720ac2a4 100644 --- a/backend/src/main/java/ddangkong/domain/member/Member.java +++ b/backend/src/main/java/ddangkong/domain/member/Member.java @@ -28,4 +28,14 @@ public class Member { @ManyToOne(optional = false, fetch = FetchType.LAZY) @JoinColumn(name = "room_id", nullable = false) private Room room; + + public Member(Long id, String nickname, Room room) { + this.id = id; + this.nickname = nickname; + this.room = room; + } + + public boolean isNotIn(Long roomId) { + return !room.getId().equals(roomId); + } } diff --git a/backend/src/test/java/ddangkong/domain/balance/option/BalanceOptionTest.java b/backend/src/test/java/ddangkong/domain/balance/option/BalanceOptionTest.java new file mode 100644 index 00000000..e9a65aea --- /dev/null +++ b/backend/src/test/java/ddangkong/domain/balance/option/BalanceOptionTest.java @@ -0,0 +1,41 @@ +package ddangkong.domain.balance.option; + +import static org.assertj.core.api.Assertions.assertThat; + +import ddangkong.domain.balance.content.BalanceContent; +import ddangkong.domain.balance.content.Category; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +class BalanceOptionTest { + + @Nested + class 특정_질문의_선택지인지_확인할_수_있다 { + + private static final BalanceContent BALANCE_CONTENT = + new BalanceContent(1L, Category.EXAMPLE, "민초 vs 반민초"); + private static final BalanceOption BALANCE_OPTION = + new BalanceOption(1L, "민초", BALANCE_CONTENT); + private static final Long CONTAIN_CONTENT_ID = 1L; + private static final Long NOT_CONTAIN_CONTENT_ID = 2L; + + @Test + void 특정_질문의_선택지가_아니다() { + // when + boolean actual = BALANCE_OPTION.isNotContained(NOT_CONTAIN_CONTENT_ID); + + // then + assertThat(actual).isTrue(); + } + + @Test + void 특정_질문의_선택지가_맞다() { + // when + boolean actual = BALANCE_OPTION.isNotContained(CONTAIN_CONTENT_ID); + + // then + assertThat(actual).isFalse(); + + } + } +} diff --git a/backend/src/test/java/ddangkong/domain/member/MemberTest.java b/backend/src/test/java/ddangkong/domain/member/MemberTest.java new file mode 100644 index 00000000..5af4f58d --- /dev/null +++ b/backend/src/test/java/ddangkong/domain/member/MemberTest.java @@ -0,0 +1,37 @@ +package ddangkong.domain.member; + +import static org.assertj.core.api.Assertions.assertThat; + +import ddangkong.domain.balance.content.Room; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +class MemberTest { + + @Nested + class 특정_방에_있는지_확인할_수_있다 { + + private static final Room ROOM = new Room(1L); + private static final Member MEMBER = new Member(1L, "rapper lee", ROOM); + private static final Long CONTAIN_ROOM_ID = 1L; + private static final Long NOT_CONTAIN_ROOM_ID = 2L; + + @Test + void 특정_방에_없다() { + // given + boolean actual = MEMBER.isNotIn(NOT_CONTAIN_ROOM_ID); + + // actual + assertThat(actual).isTrue(); + } + + @Test + void 특정_방에_있다() { + // given + boolean actual = MEMBER.isNotIn(CONTAIN_ROOM_ID); + + // actual + assertThat(actual).isFalse(); + } + } +} From d66303daf9612c60d3675223ffeb85b014303cfd Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 24 Jul 2024 18:23:19 +0900 Subject: [PATCH 0216/1013] =?UTF-8?q?feat:=20=ED=88=AC=ED=91=9C=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EB=B9=84=EC=A6=88=EB=8B=88=EC=8A=A4=20?= =?UTF-8?q?=ED=94=8C=EB=A1=9C=EC=9A=B0=20=EA=B5=AC=ED=98=84=20#15?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../balance/vote/dto/BalanceVoteRequest.java | 14 ++++ .../balance/vote/dto/BalanceVoteResponse.java | 11 +++ .../balance/content/BalanceContent.java | 6 ++ .../balance/vote/BalanceVoteService.java | 55 +++++++++++++++ .../content/BalanceContentServiceTest.java | 1 + .../balance/vote/BalanceVoteServiceTest.java | 69 +++++++++++++++++++ backend/src/test/resources/init-test.sql | 1 - 7 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteRequest.java create mode 100644 backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteResponse.java create mode 100644 backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java create mode 100644 backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java diff --git a/backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteRequest.java b/backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteRequest.java new file mode 100644 index 00000000..b14f60c0 --- /dev/null +++ b/backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteRequest.java @@ -0,0 +1,14 @@ +package ddangkong.controller.balance.vote.dto; + +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; + +public record BalanceVoteRequest( + @Positive + @NotNull + Long memberId, + @Positive + @NotNull + Long optionId +) { +} diff --git a/backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteResponse.java b/backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteResponse.java new file mode 100644 index 00000000..c7e277cf --- /dev/null +++ b/backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteResponse.java @@ -0,0 +1,11 @@ +package ddangkong.controller.balance.vote.dto; + +import ddangkong.domain.balance.vote.BalanceVote; + +public record BalanceVoteResponse( + Long optionId +) { + public BalanceVoteResponse(BalanceVote balanceVote) { + this(balanceVote.getOptionId()); + } +} diff --git a/backend/src/main/java/ddangkong/domain/balance/content/BalanceContent.java b/backend/src/main/java/ddangkong/domain/balance/content/BalanceContent.java index 5fb9026c..158806a0 100644 --- a/backend/src/main/java/ddangkong/domain/balance/content/BalanceContent.java +++ b/backend/src/main/java/ddangkong/domain/balance/content/BalanceContent.java @@ -26,4 +26,10 @@ public class BalanceContent { @Column(nullable = false) private String name; + + public BalanceContent(Long id, Category category, String name) { + this.id = id; + this.category = category; + this.name = name; + } } diff --git a/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java b/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java new file mode 100644 index 00000000..30dae02f --- /dev/null +++ b/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java @@ -0,0 +1,55 @@ +package ddangkong.service.balance.vote; + +import ddangkong.controller.balance.vote.dto.BalanceVoteRequest; +import ddangkong.controller.balance.vote.dto.BalanceVoteResponse; +import ddangkong.domain.balance.option.BalanceOption; +import ddangkong.domain.balance.option.BalanceOptionRepository; +import ddangkong.domain.balance.vote.BalanceVote; +import ddangkong.domain.balance.vote.BalanceVoteRepository; +import ddangkong.domain.member.Member; +import ddangkong.domain.member.MemberRepository; +import ddangkong.exception.BadRequestException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class BalanceVoteService { + + private final BalanceVoteRepository balanceVoteRepository; + + private final MemberRepository memberRepository; + + private final BalanceOptionRepository balanceOptionRepository; + + @Transactional + public BalanceVoteResponse createBalanceVote(BalanceVoteRequest request, Long roomId, Long contentId) { + BalanceOption balanceOption = findValidOption(request.optionId(), contentId); + Member member = findValidMember(request.memberId(), roomId); + + BalanceVote balanceVote = new BalanceVote(balanceOption, member); + BalanceVote savedBalanceVote = balanceVoteRepository.save(balanceVote); + return new BalanceVoteResponse(savedBalanceVote); + } + + private BalanceOption findValidOption(Long optionId, Long contentId) { + BalanceOption balanceOption = balanceOptionRepository.getById(optionId); + if (balanceOption.isNotContained(contentId)) { + String errorMessage = "해당 질문의 선택지가 아닙니다. contentId : %d, optionId : %d" + .formatted(contentId, optionId); + throw new BadRequestException(errorMessage); + } + return balanceOption; + } + + private Member findValidMember(Long memberId, Long roomId) { + Member member = memberRepository.getById(memberId); + if (member.isNotIn(roomId)) { + String errorMessage = "해당 방의 멤버가 아닙니다. roomId : %d, memberId : %d" + .formatted(roomId, memberId); + throw new BadRequestException(errorMessage); + } + return member; + } +} diff --git a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java index 1845abc9..638e653d 100644 --- a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java @@ -16,6 +16,7 @@ class BalanceContentServiceTest extends BaseServiceTest { @Autowired private BalanceContentService balanceContentService; + @Nested class 현재_방의_밸런스_게임_내용_조회 { diff --git a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java new file mode 100644 index 00000000..3d40ab78 --- /dev/null +++ b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java @@ -0,0 +1,69 @@ +package ddangkong.service.balance.vote; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import ddangkong.controller.balance.vote.dto.BalanceVoteRequest; +import ddangkong.controller.balance.vote.dto.BalanceVoteResponse; +import ddangkong.exception.BadRequestException; +import ddangkong.service.BaseServiceTest; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +class BalanceVoteServiceTest extends BaseServiceTest { + + @Autowired + private BalanceVoteService balanceVoteService; + + @Nested + class 투표_생성 { + + @Test + void 투표를_생성_할_수_있다() { + // given + Long optionId = 1L; + Long contentId = 1L; + Long memberId = 1L; + Long roomId = 1L; + BalanceVoteResponse expected = new BalanceVoteResponse(optionId); + + // when + BalanceVoteResponse actual = balanceVoteService.createBalanceVote( + new BalanceVoteRequest(memberId, optionId), roomId, contentId); + + // then + assertThat(actual).isEqualTo(expected); + } + + @Test + void 질문에_해당하는_선택지가_아닌_경우_예외를_던진다() { + // given + Long optionId = 1L; + Long contentId = 2L; + Long memberId = 1L; + Long roomId = 1L; + + // when & then + assertThatThrownBy(() -> balanceVoteService.createBalanceVote( + new BalanceVoteRequest(memberId, optionId), roomId, contentId)) + .isInstanceOf(BadRequestException.class) + .hasMessage("해당 질문의 선택지가 아닙니다. contentId : 2, optionId : 1"); + } + + @Test + void 방에_있지_않은_멤버인_경우_예외를_던진다() { + // given + Long optionId = 1L; + Long contentId = 1L; + Long memberId = 1L; + Long roomId = 2L; + + // when & then + assertThatThrownBy(() -> balanceVoteService.createBalanceVote( + new BalanceVoteRequest(memberId, optionId), roomId, contentId)) + .isInstanceOf(BadRequestException.class) + .hasMessage("해당 방의 멤버가 아닙니다. roomId : 2, memberId : 1"); + } + } +} diff --git a/backend/src/test/resources/init-test.sql b/backend/src/test/resources/init-test.sql index 4f1cdee0..4a9f027a 100644 --- a/backend/src/test/resources/init-test.sql +++ b/backend/src/test/resources/init-test.sql @@ -26,7 +26,6 @@ VALUES (4, 1), (4, 2), (4, 3), (4, 4), - (1, 1), (1, 2), (1, 3), (2, 4); From 23ab7d2c84f02900f06f52638bb2ca6477bc56e1 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 24 Jul 2024 18:24:57 +0900 Subject: [PATCH 0217/1013] =?UTF-8?q?feat:=20=ED=88=AC=ED=91=9C=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20API=20=EA=B5=AC=ED=98=84=20#15?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../balance/vote/BalanceVoteController.java | 33 ++++++++ .../vote/BalanceVoteControllerTest.java | 76 +++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java create mode 100644 backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java diff --git a/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java b/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java new file mode 100644 index 00000000..848cabf3 --- /dev/null +++ b/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java @@ -0,0 +1,33 @@ +package ddangkong.controller.balance.vote; + +import ddangkong.controller.balance.vote.dto.BalanceVoteRequest; +import ddangkong.controller.balance.vote.dto.BalanceVoteResponse; +import ddangkong.service.balance.vote.BalanceVoteService; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Positive; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api") +@Validated +@RequiredArgsConstructor +public class BalanceVoteController { + + private final BalanceVoteService balanceVoteService; + + @PostMapping("/balances/rooms/{roomId}/contents/{contentId}/votes") + @ResponseStatus(HttpStatus.CREATED) + public BalanceVoteResponse createBalanceVote(@PathVariable @Positive Long roomId, + @PathVariable @Positive Long contentId, + @RequestBody @Valid BalanceVoteRequest request) { + return balanceVoteService.createBalanceVote(request, roomId, contentId); + } +} diff --git a/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java new file mode 100644 index 00000000..53ea4e02 --- /dev/null +++ b/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java @@ -0,0 +1,76 @@ +package ddangkong.controller.balance.vote; + +import static org.assertj.core.api.Assertions.assertThat; + +import ddangkong.controller.BaseControllerTest; +import ddangkong.controller.balance.vote.dto.BalanceVoteRequest; +import ddangkong.controller.balance.vote.dto.BalanceVoteResponse; +import io.restassured.RestAssured; +import io.restassured.http.ContentType; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +class BalanceVoteControllerTest extends BaseControllerTest { + + @Nested + class 투표_생성 { + + private static final Long ROOM_ID = 1L; + private static final Long CONTENT_ID = 1L; + private static final BalanceVoteRequest NORMAL_REQUEST = new BalanceVoteRequest(1L, 1L); + private static final BalanceVoteResponse EXPECTED_RESPONSE = new BalanceVoteResponse(1L); + + @Test + void 현재_방의_질문을_조회할_수_있다() { + // given + BalanceVoteResponse actual = RestAssured.given().log().all() + .body(NORMAL_REQUEST).contentType(ContentType.JSON) + .pathParam("roomId", ROOM_ID) + .pathParam("contentId", CONTENT_ID) + .when().post("/api/balances/rooms/{roomId}/contents/{contentId}/votes") + .then().log().all() + .statusCode(201) + .extract().as(BalanceVoteResponse.class); + + // then + assertThat(actual).isEqualTo(EXPECTED_RESPONSE); + } + + @Test + void 요청_경로의_아이디가_양수가_아닌_경우_400_에러로_응답한다() { + // when + Long roomId = 0L; + + // given & then + assertThatCreateVoteIsBadRequest(roomId, CONTENT_ID, NORMAL_REQUEST); + } + + @Test + void 요청_바디의_아이디가_양수가_아닌_경우_400_에러로_응답한다() { + // when + BalanceVoteRequest request = new BalanceVoteRequest(0L, 1L); + + // given & then + assertThatCreateVoteIsBadRequest(ROOM_ID, CONTENT_ID, request); + } + + @Test + void 요청_바디의_아이디가_null인_경우_400_에러로_응답한다() { + // when + BalanceVoteRequest request = new BalanceVoteRequest(null, 1L); + + // given & then + assertThatCreateVoteIsBadRequest(ROOM_ID, CONTENT_ID, request); + } + + void assertThatCreateVoteIsBadRequest(Long roomId, Long contentId, BalanceVoteRequest request) { + RestAssured.given().log().all() + .body(request).contentType(ContentType.JSON) + .pathParam("roomId", roomId) + .pathParam("contentId", contentId) + .when().post("/api/balances/rooms/{roomId}/contents/{contentId}/votes") + .then().log().all() + .statusCode(400); + } + } +} From e61ea099c82a55c4be108334f19af5551bd73824 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Tue, 23 Jul 2024 19:42:54 +0900 Subject: [PATCH 0218/1013] =?UTF-8?q?chore:=20=EB=8F=99=EC=A0=81=20?= =?UTF-8?q?=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EB=9D=BC=EC=9A=B0?= =?UTF-8?q?=ED=8C=85=20=EC=84=A4=EC=A0=95=20#50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/webpack.config.common.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/webpack.config.common.js b/frontend/webpack.config.common.js index 80fd2897..9a518ee3 100644 --- a/frontend/webpack.config.common.js +++ b/frontend/webpack.config.common.js @@ -3,7 +3,6 @@ const HTMLWebpackPlugin = require('html-webpack-plugin'); const webpack = require('webpack'); const dotenv = require('dotenv'); -// this will update the process.env with environment variables in .env file dotenv.config(); module.exports = { @@ -11,6 +10,7 @@ module.exports = { output: { filename: 'bundle.js', path: path.resolve(__dirname + '/dist'), + publicPath: '/', clean: true, }, resolve: { From 0128c04dd3b722c4307b55fa7cc6288b9775dce0 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Tue, 23 Jul 2024 19:43:18 +0900 Subject: [PATCH 0219/1013] =?UTF-8?q?refactor:=20BalanceContent=20?= =?UTF-8?q?=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20#50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/mocks/data/balanceContent.json | 2 ++ frontend/src/types/balanceContent.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/frontend/src/mocks/data/balanceContent.json b/frontend/src/mocks/data/balanceContent.json index 5b1a4952..8fec9067 100644 --- a/frontend/src/mocks/data/balanceContent.json +++ b/frontend/src/mocks/data/balanceContent.json @@ -1,4 +1,6 @@ { + "totalRound": 5, + "currentRound": 1, "contentId": 1, "category": "연애", "question": "당신의 결혼 상대는?", diff --git a/frontend/src/types/balanceContent.ts b/frontend/src/types/balanceContent.ts index e619566c..f0f77949 100644 --- a/frontend/src/types/balanceContent.ts +++ b/frontend/src/types/balanceContent.ts @@ -2,6 +2,8 @@ export interface BalanceContent { contentId: number; category: string; question: string; + totalRound: number; + currentRound: number; firstOption: { optionId: number; name: string; From 752c4972e5fadfb573a191b294ce3d4c7d9be552 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Tue, 23 Jul 2024 19:47:02 +0900 Subject: [PATCH 0220/1013] =?UTF-8?q?feat:=20=EB=9D=BC=EC=9A=B0=ED=8C=85?= =?UTF-8?q?=20=EA=B2=BD=EB=A1=9C=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B4=EB=93=9C=20=ED=86=B5=EA=B3=84=20=EB=B6=84?= =?UTF-8?q?=EA=B8=B0=EC=B2=98=EB=A6=AC=20#50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SelectContainer/SelectContainer.tsx | 2 +- .../src/pages/RoundResultPage/RoundResultPage.tsx | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/SelectContainer/SelectContainer.tsx b/frontend/src/components/SelectContainer/SelectContainer.tsx index b5e96e09..8be384fd 100644 --- a/frontend/src/components/SelectContainer/SelectContainer.tsx +++ b/frontend/src/components/SelectContainer/SelectContainer.tsx @@ -13,7 +13,7 @@ const SelectContainer = () => { const [selectedId, setSelectedId] = useState(0); const goToRoundResult = () => { - navigate('/round-result'); + navigate(`/round/result`); }; const handleSelectOption = (selectedId: number) => { diff --git a/frontend/src/pages/RoundResultPage/RoundResultPage.tsx b/frontend/src/pages/RoundResultPage/RoundResultPage.tsx index c0647db9..32b325e0 100644 --- a/frontend/src/pages/RoundResultPage/RoundResultPage.tsx +++ b/frontend/src/pages/RoundResultPage/RoundResultPage.tsx @@ -7,12 +7,20 @@ import Content from '@/components/layout/Content/Content'; import NicknameList from '@/components/NicknameList/NicknameList'; import RoundVoteResult from '@/components/RoundVoteResult/RoundVoteResult'; import TopicContainer from '@/components/TopicContainer/TopicContainer'; +import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; const RoundResultPage = () => { const navigate = useNavigate(); + const { balanceContent } = useBalanceContentQuery(); + + const isLastRound = balanceContent?.currentRound === balanceContent?.totalRound; const goToGameResult = () => { - navigate('/game-result'); + navigate('/game/result'); + }; + + const goToNextRound = () => { + navigate('/game'); }; return ( @@ -22,7 +30,10 @@ const RoundResultPage = () => {
- + +
+ {activeTab === 'group' ? ( +
+
+
+
+ 100억 빚 송강 + 100억 부자 송강호 +
+
+
+ {groupResult.firstOption.percentage}% +
+
+ {groupResult.secondOption.percentage}% +
+
+
+ {groupResult.firstOption.count}명 + {groupResult.secondOption.count}명 +
+
+
+ +
+
+ ) : ( +
+
+
+
+ 100억 빚 송강 + 100억 부자 송강호 +
+
+
+ {averageResult.firstOption.percentage}% +
+
+ {averageResult.secondOption.percentage}% +
+
+
+ {averageResult.firstOption.count}명 + {averageResult.secondOption.count}명 +
+
+
+
+ )} +
+ ); +}; + +export default RoundResultTab; diff --git a/frontend/src/components/TopicContainer/TopicContainer.tsx b/frontend/src/components/TopicContainer/TopicContainer.tsx index 0c55d196..666a5fd5 100644 --- a/frontend/src/components/TopicContainer/TopicContainer.tsx +++ b/frontend/src/components/TopicContainer/TopicContainer.tsx @@ -1,13 +1,18 @@ +import { useLocation } from 'react-router-dom'; + import { categoryText, topicContainerLayout, topicText } from './TopicContainer.styled'; import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; const TopicContainer = () => { const { balanceContent } = useBalanceContentQuery(); + const location = useLocation(); + + const isGamePage = location.pathname === '/game'; return (
- {balanceContent?.category} + {isGamePage && balanceContent?.category} {balanceContent?.question}
); diff --git a/frontend/src/pages/RoundResultPage/RoundResultPage.tsx b/frontend/src/pages/RoundResultPage/RoundResultPage.tsx index 32b325e0..f1dc3235 100644 --- a/frontend/src/pages/RoundResultPage/RoundResultPage.tsx +++ b/frontend/src/pages/RoundResultPage/RoundResultPage.tsx @@ -1,11 +1,8 @@ import { useNavigate } from 'react-router-dom'; -import { NicknameListWrapper } from './RoundResultPage.styled'; - import Button from '@/components/common/Button/Button'; import Content from '@/components/layout/Content/Content'; -import NicknameList from '@/components/NicknameList/NicknameList'; -import RoundVoteResult from '@/components/RoundVoteResult/RoundVoteResult'; +import RoundResultTab from '@/components/RoundResultTab/RoundResultTab'; import TopicContainer from '@/components/TopicContainer/TopicContainer'; import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; @@ -26,10 +23,7 @@ const RoundResultPage = () => { return ( - -
- -
+
- {groupResult.firstOption.percentage}% + {animatedFirstPercentage}%
- {groupResult.secondOption.percentage}% + {animatedSecondPercentage}%
diff --git a/frontend/src/hooks/useCountAnimation.ts b/frontend/src/hooks/useCountAnimation.ts new file mode 100644 index 00000000..6abb5350 --- /dev/null +++ b/frontend/src/hooks/useCountAnimation.ts @@ -0,0 +1,35 @@ +import { useEffect, useState } from 'react'; + +// "ease out" : 빨라졌다가 천천히 끝나는 애니메이션 +const easeOutRate = (timingRate: number) => { + return timingRate === 1 ? 1 : 1 - Math.pow(2, -10 * timingRate); +}; + +interface UseCountAnimationProps { + target: number; + start?: number; + duration?: number; +} + +const useCountAnimation = ({ target, start = 50, duration = 2000 }: UseCountAnimationProps) => { + const [count, setCount] = useState(start); + const frameRate = 500 / 60; + const totalFrame = Math.round(duration / frameRate); + + useEffect(() => { + if (target === start) return; // target 값을 API로 불러올 경우 초기값이 애니메이션에 반영되므로 예외처리 + let currentNumber = start; + const counter = setInterval(() => { + const progress = easeOutRate(++currentNumber / totalFrame); + setCount(Math.round(target * progress)); + + if (progress === 1) { + clearInterval(counter); + } + }, frameRate); + }, [target, frameRate, start, totalFrame]); + + return count; +}; + +export default useCountAnimation; From a2001367ce79e1bac86b6c6ea620d37fffbfe807 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Wed, 24 Jul 2024 15:43:26 +0900 Subject: [PATCH 0225/1013] =?UTF-8?q?feat:=20roundVoteResult=20=EC=9D=B8?= =?UTF-8?q?=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=84=A0=EC=96=B8=20?= =?UTF-8?q?=EB=B0=8F=20msw=20=EC=84=A4=EC=A0=95=20#50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/constants/url.ts | 3 ++ frontend/src/mocks/data/roundVoteResult.json | 30 +++++++++++++++++++ .../mocks/handlers/balanceContentHandler.ts | 3 +- frontend/src/mocks/handlers/voteHandler.ts | 12 +++++++- frontend/src/types/roundVoteResult.ts | 28 +++++++++++++++++ 5 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 frontend/src/mocks/data/roundVoteResult.json create mode 100644 frontend/src/types/roundVoteResult.ts diff --git a/frontend/src/constants/url.ts b/frontend/src/constants/url.ts index 0200c3a8..34b2158f 100644 --- a/frontend/src/constants/url.ts +++ b/frontend/src/constants/url.ts @@ -4,9 +4,12 @@ export const API_URL = { balanceContent: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/content`, vote: (roomId: number, contentId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/contents/${contentId}/votes`, + roundVoteResult: (roomId: number, contentId: number) => + `${BASE_URL}/api/balances/rooms/${roomId}/contents/${contentId}/vote-result`, }; export const MOCK_API_URL = { balanceContent: '/api/balances/rooms/:roomId/content', vote: '/api/balances/rooms/:roomId/contents/:contentId/votes', + voteResult: '/api/balances/rooms/:roomId/contents/:contentId/vote-result', }; diff --git a/frontend/src/mocks/data/roundVoteResult.json b/frontend/src/mocks/data/roundVoteResult.json new file mode 100644 index 00000000..f2804588 --- /dev/null +++ b/frontend/src/mocks/data/roundVoteResult.json @@ -0,0 +1,30 @@ +{ + "group": { + "firstOption": { + "optionId": 1, + "name": "100억 빚 송강", + "members": ["타콩", "프콩", "마콩", "썬콩", "포콩", "미콩", "강콩"], + "memberCount": 7, + "percent": 73 + }, + "secondOption": { + "optionId": 2, + "name": "100억 부자 송강호", + "members": ["커콩", "든콩", "조콩"], + "memberCount": 3, + "percent": 27 + } + }, + "total": { + "firstOption": { + "optionId": 1, + "name": "100억 빚 송강", + "percent": 16 + }, + "secondOption": { + "optionId": 2, + "name": "100억 부자 송강호", + "percent": 84 + } + } +} diff --git a/frontend/src/mocks/handlers/balanceContentHandler.ts b/frontend/src/mocks/handlers/balanceContentHandler.ts index 53921c9e..a7ecd3ae 100644 --- a/frontend/src/mocks/handlers/balanceContentHandler.ts +++ b/frontend/src/mocks/handlers/balanceContentHandler.ts @@ -3,9 +3,10 @@ import { http, HttpResponse } from 'msw'; import BALANCE_CONTENT from '../data/balanceContent.json'; import { MOCK_API_URL } from '@/constants/url'; +import { BalanceContent } from '@/types/balanceContent'; const fetchBalanceContentHandler = () => { - return HttpResponse.json(BALANCE_CONTENT); + return HttpResponse.json(BALANCE_CONTENT); }; export const contentHandler = [http.get(MOCK_API_URL.balanceContent, fetchBalanceContentHandler)]; diff --git a/frontend/src/mocks/handlers/voteHandler.ts b/frontend/src/mocks/handlers/voteHandler.ts index a8dc35b2..641496b0 100644 --- a/frontend/src/mocks/handlers/voteHandler.ts +++ b/frontend/src/mocks/handlers/voteHandler.ts @@ -1,6 +1,9 @@ import { http, HttpResponse } from 'msw'; +import VOTE_RESULT from '../data/roundVoteResult.json'; + import { MOCK_API_URL } from '@/constants/url'; +import { RoundVoteResult } from '@/types/roundVoteResult'; const voteBalanceContentHandler = async ({ request }: { request: Request }) => { const body = await request.json(); @@ -13,4 +16,11 @@ const voteBalanceContentHandler = async ({ request }: { request: Request }) => { ); }; -export const voteHandler = [http.post(MOCK_API_URL.vote, voteBalanceContentHandler)]; +const fetchVoteResultHandler = async () => { + return HttpResponse.json(VOTE_RESULT); +}; + +export const voteHandler = [ + http.post(MOCK_API_URL.vote, voteBalanceContentHandler), + http.get(MOCK_API_URL.voteResult, fetchVoteResultHandler), +]; diff --git a/frontend/src/types/roundVoteResult.ts b/frontend/src/types/roundVoteResult.ts new file mode 100644 index 00000000..319b4c7d --- /dev/null +++ b/frontend/src/types/roundVoteResult.ts @@ -0,0 +1,28 @@ +export interface RoundVoteResult { + group: Group; + total: Total; +} + +export interface Group { + firstOption: GroupOption; + secondOption: GroupOption; +} + +export interface Total { + firstOption: AverageOption; + secondOption: AverageOption; +} + +export interface GroupOption { + optionId: number; + name: string; + members: string[]; + memberCount: number; + percent: number; +} + +export interface AverageOption { + optionId: number; + name: string; + percent: number; +} From be3f49ac72f1c011d51aed0a2ef4d3143734fd08 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Wed, 24 Jul 2024 19:15:07 +0900 Subject: [PATCH 0226/1013] =?UTF-8?q?refactor:=20=EA=B7=B8=EB=A3=B9=20?= =?UTF-8?q?=ED=86=B5=EA=B3=84=EC=99=80=20=EC=A0=84=EC=B2=B4=20=ED=86=B5?= =?UTF-8?q?=EA=B3=84=20=EC=84=9C=EB=B2=84=20=EC=83=81=ED=83=9C=EB=A5=BC=20?= =?UTF-8?q?react-query=EB=A1=9C=20=EA=B4=80=EB=A6=AC=20#50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/balanceContent.ts | 11 +++ .../RoundResultTab/RoundResultTab.tsx | 74 ++++--------------- frontend/src/hooks/useCountAnimation.ts | 4 +- frontend/src/hooks/useRoundVoteResultQuery.ts | 20 +++++ frontend/src/types/roundVoteResult.ts | 11 +-- 5 files changed, 50 insertions(+), 70 deletions(-) create mode 100644 frontend/src/hooks/useRoundVoteResultQuery.ts diff --git a/frontend/src/apis/balanceContent.ts b/frontend/src/apis/balanceContent.ts index c000cb59..de9a5bc7 100644 --- a/frontend/src/apis/balanceContent.ts +++ b/frontend/src/apis/balanceContent.ts @@ -2,6 +2,7 @@ import fetcher from './fetcher'; import { API_URL } from '@/constants/url'; import { BalanceContent } from '@/types/balanceContent'; +import { RoundVoteResult } from '@/types/roundVoteResult'; export const fetchBalanceContent = async (roomId = 1): Promise => { const res = await fetcher.get({ url: API_URL.balanceContent(roomId) }); @@ -24,3 +25,13 @@ export const voteBalanceContent = async (optionId: number, roomId = 1, contentId return data; }; + +export const fetchRoundVoteResult = async (roomId = 1, contentId = 1): Promise => { + const res = await fetcher.get({ + url: API_URL.roundVoteResult(roomId, contentId), + }); + + const data = await res.json(); + + return data; +}; diff --git a/frontend/src/components/RoundResultTab/RoundResultTab.tsx b/frontend/src/components/RoundResultTab/RoundResultTab.tsx index 44fbbf2c..af1e23e5 100644 --- a/frontend/src/components/RoundResultTab/RoundResultTab.tsx +++ b/frontend/src/components/RoundResultTab/RoundResultTab.tsx @@ -1,78 +1,30 @@ -import { useEffect, useState } from 'react'; +import { useState } from 'react'; +import { useTotalCountAnimation } from './RoundResultTab.hook'; import { - barBackgroundStyle, - barStyle, - barWrapperStyle, blankWrapper, - buttonStyle, - categoryContainer, contentWrapperStyle, - currentVoteButtonWrapper, - resultTextStyle, - roundVoteResultContainer, tabButtonStyle, tabLayout, tabWrapperStyle, } from './RoundResultTab.styled'; +import GroupRoundResultTab from '../GroupRoundResultTab/GroupRoundResultTab'; +import TotalResultTab from '../TotalResultTab/TotalResultTab'; -import useCountAnimation from '@/hooks/useCountAnimation'; - -interface Option { - percentage: number; - count: number; -} - -interface Statistic { - firstOption: Option; - secondOption: Option; -} - -const INITIAL_STATISTIC: Statistic = { - firstOption: { - percentage: 50, - count: 0, - }, - secondOption: { - percentage: 50, - count: 0, - }, -}; +import useRoundVoteResultQuery from '@/hooks/useRoundVoteResultQuery'; const RoundResultTab = () => { const [activeTab, setActiveTab] = useState('group'); - const [groupResult, setGroupResult] = useState(INITIAL_STATISTIC); - const [averageResult, setAverageResult] = useState(INITIAL_STATISTIC); - - const animatedFirstPercentage = useCountAnimation({ target: groupResult.firstOption.percentage }); - const animatedSecondPercentage = useCountAnimation({ - target: groupResult.secondOption.percentage, - }); - - const isBigFirstOption = groupResult.firstOption.percentage >= 50; - - useEffect(() => { - const fetchData = async () => { - const groupResponse = await new Promise((resolve) => - resolve({ - firstOption: { percentage: 73, count: 7 }, - secondOption: { percentage: 27, count: 3 }, - }), - ); - - const averageResponse = await new Promise((resolve) => - resolve({ - firstOption: { percentage: 16, count: 16 }, - secondOption: { percentage: 84, count: 84 }, - }), - ); + const { groupRoundResult, totalResult } = useRoundVoteResultQuery(); - setGroupResult(groupResponse); - setAverageResult(averageResponse); - }; + const { + animatedFirstPercent, + animatedSecondPercent, + animatedTotalFirstPercent, + animatedTotalSecondPercent, + } = useTotalCountAnimation(groupRoundResult, totalResult); - fetchData(); - }, []); + if (!groupRoundResult || !totalResult) return
데이터가 없습니다
; return (
diff --git a/frontend/src/hooks/useCountAnimation.ts b/frontend/src/hooks/useCountAnimation.ts index 6abb5350..3a092158 100644 --- a/frontend/src/hooks/useCountAnimation.ts +++ b/frontend/src/hooks/useCountAnimation.ts @@ -6,7 +6,7 @@ const easeOutRate = (timingRate: number) => { }; interface UseCountAnimationProps { - target: number; + target?: number; start?: number; duration?: number; } @@ -17,7 +17,7 @@ const useCountAnimation = ({ target, start = 50, duration = 2000 }: UseCountAnim const totalFrame = Math.round(duration / frameRate); useEffect(() => { - if (target === start) return; // target 값을 API로 불러올 경우 초기값이 애니메이션에 반영되므로 예외처리 + if (typeof target === 'undefined' || target === start) return; // target 값을 API로 불러올 경우 초기값이 애니메이션에 반영되므로 예외처리 let currentNumber = start; const counter = setInterval(() => { const progress = easeOutRate(++currentNumber / totalFrame); diff --git a/frontend/src/hooks/useRoundVoteResultQuery.ts b/frontend/src/hooks/useRoundVoteResultQuery.ts new file mode 100644 index 00000000..b0ee2807 --- /dev/null +++ b/frontend/src/hooks/useRoundVoteResultQuery.ts @@ -0,0 +1,20 @@ +import { useQuery } from '@tanstack/react-query'; + +import { fetchRoundVoteResult } from '@/apis/balanceContent'; + +const useRoundVoteResultQuery = () => { + const roundVoteResultQuery = useQuery({ + queryKey: ['roundVoteResult'], + queryFn: async () => await fetchRoundVoteResult(), + }); + + roundVoteResultQuery.data?.group; + + return { + ...roundVoteResultQuery, + groupRoundResult: roundVoteResultQuery.data?.group, + totalResult: roundVoteResultQuery.data?.total, + }; +}; + +export default useRoundVoteResultQuery; diff --git a/frontend/src/types/roundVoteResult.ts b/frontend/src/types/roundVoteResult.ts index 319b4c7d..00297a8d 100644 --- a/frontend/src/types/roundVoteResult.ts +++ b/frontend/src/types/roundVoteResult.ts @@ -9,19 +9,16 @@ export interface Group { } export interface Total { - firstOption: AverageOption; - secondOption: AverageOption; + firstOption: TotalOption; + secondOption: TotalOption; } -export interface GroupOption { - optionId: number; - name: string; +export interface GroupOption extends TotalOption { members: string[]; memberCount: number; - percent: number; } -export interface AverageOption { +export interface TotalOption { optionId: number; name: string; percent: number; From 71032612a76d28c573c684a27d3647541b5c6efa Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Wed, 24 Jul 2024 19:15:48 +0900 Subject: [PATCH 0227/1013] =?UTF-8?q?refactor:=20=EA=B7=B8=EB=A3=B9=20?= =?UTF-8?q?=ED=86=B5=EA=B3=84=EC=99=80=20=EC=A0=84=EC=B2=B4=20=ED=86=B5?= =?UTF-8?q?=EA=B3=84=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC=20#50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GroupRoundResultTab.tsx | 54 +++++++++++++++ .../RoundResultTab/RoundResultTab.hook.ts | 21 ++++++ .../RoundResultTab/RoundResultTab.tsx | 67 +++++-------------- .../TotalResultTab/TotalResultTab.tsx | 47 +++++++++++++ 4 files changed, 138 insertions(+), 51 deletions(-) create mode 100644 frontend/src/components/GroupRoundResultTab/GroupRoundResultTab.tsx create mode 100644 frontend/src/components/RoundResultTab/RoundResultTab.hook.ts create mode 100644 frontend/src/components/TotalResultTab/TotalResultTab.tsx diff --git a/frontend/src/components/GroupRoundResultTab/GroupRoundResultTab.tsx b/frontend/src/components/GroupRoundResultTab/GroupRoundResultTab.tsx new file mode 100644 index 00000000..c1152023 --- /dev/null +++ b/frontend/src/components/GroupRoundResultTab/GroupRoundResultTab.tsx @@ -0,0 +1,54 @@ +import { + barBackgroundStyle, + barStyle, + barWrapperStyle, + buttonStyle, + categoryContainer, + currentVoteButtonWrapper, + resultTextStyle, + roundVoteResultContainer, +} from '../RoundResultTab/RoundResultTab.styled'; + +import { Group } from '@/types/roundVoteResult'; + +interface GroupRoundResultTabProps { + groupRoundResult: Group; + animatedFirstPercent?: number; + animatedSecondPercent?: number; +} + +const GroupRoundResultTab = ({ + groupRoundResult, + animatedFirstPercent, + animatedSecondPercent, +}: GroupRoundResultTabProps) => { + const isBigFirstOption = groupRoundResult.firstOption.percent >= 50; + + return ( + <> +
+
+ {groupRoundResult.firstOption.name} + {groupRoundResult.secondOption.name} +
+
+
+ {animatedFirstPercent}% +
+
+ {animatedSecondPercent}% +
+
+
+ {groupRoundResult.firstOption.memberCount}명 + {groupRoundResult.secondOption.memberCount}명 +
+
+
+ +
+ + ); +}; + +export default GroupRoundResultTab; diff --git a/frontend/src/components/RoundResultTab/RoundResultTab.hook.ts b/frontend/src/components/RoundResultTab/RoundResultTab.hook.ts new file mode 100644 index 00000000..5e5672d8 --- /dev/null +++ b/frontend/src/components/RoundResultTab/RoundResultTab.hook.ts @@ -0,0 +1,21 @@ +import useCountAnimation from '@/hooks/useCountAnimation'; +import { Total, Group } from '@/types/roundVoteResult'; + +export const useTotalCountAnimation = (groupRoundResult?: Group, totalResult?: Total) => { + const animatedFirstPercent = useCountAnimation({ target: groupRoundResult?.firstOption.percent }); + const animatedSecondPercent = useCountAnimation({ + target: groupRoundResult?.secondOption.percent, + }); + + const animatedTotalFirstPercent = useCountAnimation({ target: totalResult?.firstOption.percent }); + const animatedTotalSecondPercent = useCountAnimation({ + target: totalResult?.secondOption.percent, + }); + + return { + animatedFirstPercent, + animatedSecondPercent, + animatedTotalFirstPercent, + animatedTotalSecondPercent, + }; +}; diff --git a/frontend/src/components/RoundResultTab/RoundResultTab.tsx b/frontend/src/components/RoundResultTab/RoundResultTab.tsx index af1e23e5..f86310b9 100644 --- a/frontend/src/components/RoundResultTab/RoundResultTab.tsx +++ b/frontend/src/components/RoundResultTab/RoundResultTab.tsx @@ -44,57 +44,22 @@ const RoundResultTab = () => { 전체
- {activeTab === 'group' ? ( -
-
-
-
- 100억 빚 송강 - 100억 부자 송강호 -
-
-
- {animatedFirstPercentage}% -
-
- {animatedSecondPercentage}% -
-
-
- {groupResult.firstOption.count}명 - {groupResult.secondOption.count}명 -
-
-
- -
-
- ) : ( -
-
-
-
- 100억 빚 송강 - 100억 부자 송강호 -
-
-
- {averageResult.firstOption.percentage}% -
-
- {averageResult.secondOption.percentage}% -
-
-
- {averageResult.firstOption.count}명 - {averageResult.secondOption.count}명 -
-
-
-
- )} +
+
+ {activeTab === 'group' ? ( + + ) : ( + + )} +
); }; diff --git a/frontend/src/components/TotalResultTab/TotalResultTab.tsx b/frontend/src/components/TotalResultTab/TotalResultTab.tsx new file mode 100644 index 00000000..fdba2a5e --- /dev/null +++ b/frontend/src/components/TotalResultTab/TotalResultTab.tsx @@ -0,0 +1,47 @@ +import { + barBackgroundStyle, + barStyle, + barWrapperStyle, + blankWrapper, + categoryContainer, + roundVoteResultContainer, +} from '../RoundResultTab/RoundResultTab.styled'; + +import { Total } from '@/types/roundVoteResult'; + +interface TotalResultTabProps { + totalResult: Total; + animatedTotalFirstPercent?: number; + animatedTotalSecondPercent?: number; +} + +const TotalResultTab = ({ + totalResult, + animatedTotalFirstPercent, + animatedTotalSecondPercent, +}: TotalResultTabProps) => { + const isBigFirstOption = totalResult.firstOption.percent >= 50; + + return ( + <> +
+
+ {totalResult.firstOption.name} + {totalResult.secondOption.name} +
+
+
+ {animatedTotalFirstPercent}% +
+
+ {animatedTotalSecondPercent}% +
+
+
+
+
+ + ); +}; + +export default TotalResultTab; From 2d269033334cf93ef029ab459d339068d34a2bda Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Wed, 24 Jul 2024 20:09:29 +0900 Subject: [PATCH 0228/1013] =?UTF-8?q?refactor:=20Header=20=ED=99=88=20?= =?UTF-8?q?=EC=95=84=EC=9D=B4=EC=BD=98=20=EB=8C=80=EC=8B=A0=20=ED=98=84?= =?UTF-8?q?=EC=9E=AC=20=EB=9D=BC=EC=9A=B4=EB=93=9C=20=ED=91=9C=EC=8B=9C=20?= =?UTF-8?q?#50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SelectContainer/SelectContainer.tsx | 3 ++- .../components/common/Button/Button.styled.ts | 1 - .../components/layout/Header/Header.styled.ts | 5 +++++ .../src/components/layout/Header/Header.tsx | 17 ++++++----------- frontend/src/pages/MainPage/MainPage.styled.ts | 2 +- .../pages/NicknamePage/NicknamePage.styled.ts | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/frontend/src/components/SelectContainer/SelectContainer.tsx b/frontend/src/components/SelectContainer/SelectContainer.tsx index 8be384fd..a873db46 100644 --- a/frontend/src/components/SelectContainer/SelectContainer.tsx +++ b/frontend/src/components/SelectContainer/SelectContainer.tsx @@ -39,7 +39,8 @@ const SelectContainer = () => { handleSelectOption={handleSelectOption} /> -
)} diff --git a/frontend/src/components/common/Button/Button.styled.ts b/frontend/src/components/common/Button/Button.styled.ts index 930ce79d..f91662fe 100644 --- a/frontend/src/components/common/Button/Button.styled.ts +++ b/frontend/src/components/common/Button/Button.styled.ts @@ -24,7 +24,6 @@ export const buttonLayout = ({ disabled, size, radius, fontSize }: ButtonLayoutP background-color: ${disabled ? Theme.color.peanut300 : Theme.color.peanut400}; font-weight: bold; - font-size: ${getFontSize(fontSize)}; cursor: ${disabled ? 'not-allowed' : 'pointer'}; diff --git a/frontend/src/components/layout/Header/Header.styled.ts b/frontend/src/components/layout/Header/Header.styled.ts index 0e19358f..010eb692 100644 --- a/frontend/src/components/layout/Header/Header.styled.ts +++ b/frontend/src/components/layout/Header/Header.styled.ts @@ -7,6 +7,11 @@ export const headerLayout = css` height: 8rem; `; +export const roundText = css` + font-weight: bold; + font-size: 1.6rem; +`; + export const gameTitle = css` font-weight: bold; font-size: 1.6rem; diff --git a/frontend/src/components/layout/Header/Header.tsx b/frontend/src/components/layout/Header/Header.tsx index 026d6331..9e7b4e1b 100644 --- a/frontend/src/components/layout/Header/Header.tsx +++ b/frontend/src/components/layout/Header/Header.tsx @@ -1,25 +1,20 @@ -import { useNavigate } from 'react-router-dom'; +import { gameTitle, headerLayout, roundText } from './Header.styled'; -import { gameTitle, headerLayout } from './Header.styled'; - -import HomeIcon from '@/assets/images/homeIcon.svg'; import SettingsIcon from '@/assets/images/settingsIcon.svg'; +import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; interface HeaderProps { title: string; } const Header = ({ title }: HeaderProps) => { - const navigate = useNavigate(); + const { balanceContent } = useBalanceContentQuery(); - const goToHome = () => { - navigate('/'); - }; return (
- + + {balanceContent?.currentRound}/{balanceContent?.totalRound} + {title} ); From d8a6d5348392ca258c52feed188d6fd62b810ce6 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Wed, 24 Jul 2024 20:49:18 +0900 Subject: [PATCH 0231/1013] =?UTF-8?q?feat:=20=EB=8B=A4=EC=9D=8C=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B4=EB=93=9C=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=ED=95=98=EB=8A=94=20API=20=ED=86=B5=EC=8B=A0=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20#50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/balanceContent.ts | 10 ++++++++++ frontend/src/constants/url.ts | 4 +++- frontend/src/mocks/handlers/voteHandler.ts | 11 ++++++++++- .../src/pages/RoundResultPage/RoundResultPage.tsx | 4 +++- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/frontend/src/apis/balanceContent.ts b/frontend/src/apis/balanceContent.ts index de9a5bc7..5a5b57bb 100644 --- a/frontend/src/apis/balanceContent.ts +++ b/frontend/src/apis/balanceContent.ts @@ -35,3 +35,13 @@ export const fetchRoundVoteResult = async (roomId = 1, contentId = 1): Promise => { + const res = await fetcher.post({ + url: API_URL.moveNextRound(roomId), + }); + + const data = await res.json(); + + return data; +}; diff --git a/frontend/src/constants/url.ts b/frontend/src/constants/url.ts index 34b2158f..ffac7c08 100644 --- a/frontend/src/constants/url.ts +++ b/frontend/src/constants/url.ts @@ -6,10 +6,12 @@ export const API_URL = { `${BASE_URL}/api/balances/rooms/${roomId}/contents/${contentId}/votes`, roundVoteResult: (roomId: number, contentId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/contents/${contentId}/vote-result`, + moveNextRound: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/contents`, }; export const MOCK_API_URL = { balanceContent: '/api/balances/rooms/:roomId/content', vote: '/api/balances/rooms/:roomId/contents/:contentId/votes', - voteResult: '/api/balances/rooms/:roomId/contents/:contentId/vote-result', + roundVoteResult: '/api/balances/rooms/:roomId/contents/:contentId/vote-result', + moveNextRound: '/api/balances/rooms/:roomId/contents', }; diff --git a/frontend/src/mocks/handlers/voteHandler.ts b/frontend/src/mocks/handlers/voteHandler.ts index 641496b0..e715d24e 100644 --- a/frontend/src/mocks/handlers/voteHandler.ts +++ b/frontend/src/mocks/handlers/voteHandler.ts @@ -1,8 +1,10 @@ import { http, HttpResponse } from 'msw'; +import BALANCE_CONTENT from '../data/balanceContent.json'; import VOTE_RESULT from '../data/roundVoteResult.json'; import { MOCK_API_URL } from '@/constants/url'; +import { BalanceContent } from '@/types/balanceContent'; import { RoundVoteResult } from '@/types/roundVoteResult'; const voteBalanceContentHandler = async ({ request }: { request: Request }) => { @@ -20,7 +22,14 @@ const fetchVoteResultHandler = async () => { return HttpResponse.json(VOTE_RESULT); }; +const goToNextRoundHandler = () => { + BALANCE_CONTENT.currentRound += 1; + + return HttpResponse.json(BALANCE_CONTENT, { status: 201 }); +}; + export const voteHandler = [ http.post(MOCK_API_URL.vote, voteBalanceContentHandler), - http.get(MOCK_API_URL.voteResult, fetchVoteResultHandler), + http.get(MOCK_API_URL.roundVoteResult, fetchVoteResultHandler), + http.post(MOCK_API_URL.moveNextRound, goToNextRoundHandler), ]; diff --git a/frontend/src/pages/RoundResultPage/RoundResultPage.tsx b/frontend/src/pages/RoundResultPage/RoundResultPage.tsx index f1dc3235..30876e02 100644 --- a/frontend/src/pages/RoundResultPage/RoundResultPage.tsx +++ b/frontend/src/pages/RoundResultPage/RoundResultPage.tsx @@ -1,5 +1,6 @@ import { useNavigate } from 'react-router-dom'; +import { moveNextRound } from '@/apis/balanceContent'; import Button from '@/components/common/Button/Button'; import Content from '@/components/layout/Content/Content'; import RoundResultTab from '@/components/RoundResultTab/RoundResultTab'; @@ -16,7 +17,8 @@ const RoundResultPage = () => { navigate('/game/result'); }; - const goToNextRound = () => { + const goToNextRound = async () => { + await moveNextRound(); navigate('/game'); }; From 5e2696f03165d03db07d61267d72e4281d04a0ca Mon Sep 17 00:00:00 2001 From: Eden <84304802+PgmJun@users.noreply.github.com> Date: Wed, 24 Jul 2024 20:58:07 +0900 Subject: [PATCH 0232/1013] =?UTF-8?q?chore:=20cd=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=BD=ED=8A=B8=20application-dev.yml=20=EC=84=B8=ED=8C=85?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=9E=91=EC=84=B1=20#61?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 535e4de4..b56df492 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -28,6 +28,10 @@ jobs: distribution: 'temurin' java-version: '17' + - name: Setting application.yml + run: | + echo ${{ secrets.application-yml-dev }} > src/main/resources/application-dev.yml + - name: Grant execute permission for gradlew run: chmod +x gradlew From e69fbcc54dde8b9de779efc8df60bb74320e6c66 Mon Sep 17 00:00:00 2001 From: Eden <84304802+PgmJun@users.noreply.github.com> Date: Wed, 24 Jul 2024 20:59:37 +0900 Subject: [PATCH 0233/1013] =?UTF-8?q?chore:=20application-dev.yml=20Action?= =?UTF-8?q?s=20Secrets=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD=20#61?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index b56df492..79f7ddc9 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -30,7 +30,7 @@ jobs: - name: Setting application.yml run: | - echo ${{ secrets.application-yml-dev }} > src/main/resources/application-dev.yml + echo ${{ secrets.APPLICATION_DEV_YML }} > src/main/resources/application-dev.yml - name: Grant execute permission for gradlew run: chmod +x gradlew From 90c834dda09908b19a6daec74c8289b64dfda074 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 24 Jul 2024 21:08:54 +0900 Subject: [PATCH 0234/1013] =?UTF-8?q?style:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EC=97=90=20=EC=9E=98=EB=AA=BB=20=EC=9E=91=EC=84=B1=ED=95=9C=20?= =?UTF-8?q?=EC=A3=BC=EC=84=9D=20=EC=88=98=EC=A0=95=20#15?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/test/java/ddangkong/domain/member/MemberTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/src/test/java/ddangkong/domain/member/MemberTest.java b/backend/src/test/java/ddangkong/domain/member/MemberTest.java index 5af4f58d..1172bbe3 100644 --- a/backend/src/test/java/ddangkong/domain/member/MemberTest.java +++ b/backend/src/test/java/ddangkong/domain/member/MemberTest.java @@ -18,19 +18,19 @@ class 특정_방에_있는지_확인할_수_있다 { @Test void 특정_방에_없다() { - // given + // when boolean actual = MEMBER.isNotIn(NOT_CONTAIN_ROOM_ID); - // actual + // then assertThat(actual).isTrue(); } @Test void 특정_방에_있다() { - // given + // when boolean actual = MEMBER.isNotIn(CONTAIN_ROOM_ID); - // actual + // then assertThat(actual).isFalse(); } } From 5691227f9334dfe312f5bab51a897ecef5465b85 Mon Sep 17 00:00:00 2001 From: Eden <84304802+PgmJun@users.noreply.github.com> Date: Wed, 24 Jul 2024 21:10:29 +0900 Subject: [PATCH 0235/1013] =?UTF-8?q?fix:=20application-dev.yml=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=83=9D=EC=84=B1=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=BD=ED=8A=B8=20=EC=B6=94=EA=B0=80=20#61?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 79f7ddc9..15046c92 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -30,7 +30,8 @@ jobs: - name: Setting application.yml run: | - echo ${{ secrets.APPLICATION_DEV_YML }} > src/main/resources/application-dev.yml + touch ./src/main/resources/application-dev.yml + echo ${{ secrets.APPLICATION_DEV_YML }} > ./src/main/resources/application-dev.yml - name: Grant execute permission for gradlew run: chmod +x gradlew From 02b457435a0b6b1f812e573fb962a5d2f343f9d0 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Wed, 24 Jul 2024 21:15:42 +0900 Subject: [PATCH 0236/1013] =?UTF-8?q?fix:=20application-dev=20=EC=84=B8?= =?UTF-8?q?=ED=8C=85=20=EB=A1=9C=EC=A7=81=20=EC=9C=84=EC=B9=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20#61?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 15046c92..8bb7b063 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -19,8 +19,11 @@ jobs: working-directory: ./backend steps: - - name: Checkout code + - name: Checkout code and Setting application.yml uses: actions/checkout@v4 + run: | + touch ./src/main/resources/application-dev.yml + echo ${{ secrets.APPLICATION_DEV_YML }} > ./src/main/resources/application-dev.yml - name: Set up JDK 17 uses: actions/setup-java@v4 @@ -28,11 +31,6 @@ jobs: distribution: 'temurin' java-version: '17' - - name: Setting application.yml - run: | - touch ./src/main/resources/application-dev.yml - echo ${{ secrets.APPLICATION_DEV_YML }} > ./src/main/resources/application-dev.yml - - name: Grant execute permission for gradlew run: chmod +x gradlew From e78daa87d14fe906b474f14e3a58a0489854fd01 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Wed, 24 Jul 2024 21:17:31 +0900 Subject: [PATCH 0237/1013] =?UTF-8?q?fix:=20application-dev=20=EC=84=B8?= =?UTF-8?q?=ED=8C=85=20=EB=A1=9C=EC=A7=81=20=EC=9C=84=EC=B9=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20#61?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 8bb7b063..5ef589fd 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -19,8 +19,10 @@ jobs: working-directory: ./backend steps: - - name: Checkout code and Setting application.yml + - name: Checkout code uses: actions/checkout@v4 + + - name: Setting application-dev.yml run: | touch ./src/main/resources/application-dev.yml echo ${{ secrets.APPLICATION_DEV_YML }} > ./src/main/resources/application-dev.yml From b9483d141a9226e590ad488387cad17b6428a5a1 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Wed, 24 Jul 2024 21:19:31 +0900 Subject: [PATCH 0238/1013] =?UTF-8?q?fix:=20echo=20=EB=A1=9C=EC=A7=81=20pr?= =?UTF-8?q?intf=20=EB=A1=9C=20=EC=88=98=EC=A0=95=20#61?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 5ef589fd..28d0aaad 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -24,8 +24,7 @@ jobs: - name: Setting application-dev.yml run: | - touch ./src/main/resources/application-dev.yml - echo ${{ secrets.APPLICATION_DEV_YML }} > ./src/main/resources/application-dev.yml + printf "%s" "${{ secrets.APPLICATION_DEV_YML }}" > ./src/main/resources/application-dev.yml - name: Set up JDK 17 uses: actions/setup-java@v4 From a73485aed37ea9d040f74111348a3ecd1e7c6b5c Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Wed, 24 Jul 2024 21:27:20 +0900 Subject: [PATCH 0239/1013] =?UTF-8?q?chore:=20dev=20=EC=95=A0=ED=94=8C?= =?UTF-8?q?=EB=A6=AC=EC=BC=80=EC=9D=B4=EC=85=98=20=EC=84=9C=EB=B2=84=20noh?= =?UTF-8?q?up=20=ED=8C=8C=EC=9D=BC=EC=97=90=20=EC=95=A0=ED=94=8C=EB=A6=AC?= =?UTF-8?q?=EC=BC=80=EC=9D=B4=EC=85=98=20=EB=A1=9C=EA=B7=B8=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=20=EB=A1=9C=EC=A7=81=20=EC=9E=91=EC=84=B1=20#61?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 28d0aaad..d512bd82 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -79,6 +79,6 @@ jobs: fi - name: Run new Docker container - run: | - sudo docker run -d --name $CONTAINER_NAME \ - $DOCKER_REPOSITORY_NAME:latest + run: | + sudo nohup docker run --name $CONTAINER_NAME \ + $DOCKER_REPOSITORY_NAME:latest > nohup.out 2>&1 & From 092b208e87c534b5897d908a58557d414c7b5ac1 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Wed, 24 Jul 2024 21:38:34 +0900 Subject: [PATCH 0240/1013] =?UTF-8?q?chore:=20dev=20=EC=95=A0=ED=94=8C?= =?UTF-8?q?=EB=A6=AC=EC=BC=80=EC=9D=B4=EC=85=98=20=EC=84=9C=EB=B2=84=20noh?= =?UTF-8?q?up=20=ED=8C=8C=EC=9D=BC=20=EC=9C=84=EC=B9=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20#61?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index d512bd82..19fba87e 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -81,4 +81,4 @@ jobs: - name: Run new Docker container run: | sudo nohup docker run --name $CONTAINER_NAME \ - $DOCKER_REPOSITORY_NAME:latest > nohup.out 2>&1 & + $DOCKER_REPOSITORY_NAME:latest > ~/dev-nohup.out 2>&1 & From f46054ddffb8a51d7b1ee318372bd0cf7bb4c0c6 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Wed, 24 Jul 2024 22:52:44 +0900 Subject: [PATCH 0241/1013] =?UTF-8?q?feat:=20=EC=B5=9C=EC=A2=85=20?= =?UTF-8?q?=EA=B2=8C=EC=9E=84=20=EA=B2=B0=EA=B3=BC=20=EB=B6=88=EB=9F=AC?= =?UTF-8?q?=EC=98=A4=EB=8A=94=20API=20=EA=B5=AC=ED=98=84=20#50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/balanceContent.ts | 12 ++++++- frontend/src/constants/url.ts | 2 ++ frontend/src/mocks/data/finalResult.json | 37 ++++++++++++++++++++++ frontend/src/mocks/handlers/voteHandler.ts | 6 ++++ frontend/src/types/balanceContent.ts | 6 ++++ 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 frontend/src/mocks/data/finalResult.json diff --git a/frontend/src/apis/balanceContent.ts b/frontend/src/apis/balanceContent.ts index 5a5b57bb..88ee6da4 100644 --- a/frontend/src/apis/balanceContent.ts +++ b/frontend/src/apis/balanceContent.ts @@ -1,7 +1,7 @@ import fetcher from './fetcher'; import { API_URL } from '@/constants/url'; -import { BalanceContent } from '@/types/balanceContent'; +import { BalanceContent, FinalGameResult } from '@/types/balanceContent'; import { RoundVoteResult } from '@/types/roundVoteResult'; export const fetchBalanceContent = async (roomId = 1): Promise => { @@ -45,3 +45,13 @@ export const moveNextRound = async (roomId = 1): Promise => { return data; }; + +export const fetchFinalGameResult = async (roomId = 1): Promise => { + const res = await fetcher.get({ + url: API_URL.finalResult(roomId), + }); + + const data = await res.json(); + + return data; +}; diff --git a/frontend/src/constants/url.ts b/frontend/src/constants/url.ts index ffac7c08..ca92cbf3 100644 --- a/frontend/src/constants/url.ts +++ b/frontend/src/constants/url.ts @@ -7,6 +7,7 @@ export const API_URL = { roundVoteResult: (roomId: number, contentId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/contents/${contentId}/vote-result`, moveNextRound: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/contents`, + finalResult: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/final`, }; export const MOCK_API_URL = { @@ -14,4 +15,5 @@ export const MOCK_API_URL = { vote: '/api/balances/rooms/:roomId/contents/:contentId/votes', roundVoteResult: '/api/balances/rooms/:roomId/contents/:contentId/vote-result', moveNextRound: '/api/balances/rooms/:roomId/contents', + finalResult: '/api/balances/rooms/:roomId/final', }; diff --git a/frontend/src/mocks/data/finalResult.json b/frontend/src/mocks/data/finalResult.json new file mode 100644 index 00000000..6ff5cc05 --- /dev/null +++ b/frontend/src/mocks/data/finalResult.json @@ -0,0 +1,37 @@ +[ + { + "rank": 1, + "name": "타콩", + "percent": 100 + }, + { + "rank": 2, + "name": "프콩", + "percent": 80 + }, + { + "rank": 3, + "name": "마콩", + "percent": 80 + }, + { + "rank": 4, + "name": "썬콩", + "percent": 60 + }, + { + "rank": 5, + "name": "포콩", + "percent": 40 + }, + { + "rank": 6, + "name": "강콩", + "percent": 20 + }, + { + "rank": 7, + "name": "프콩", + "percent": 0 + } +] diff --git a/frontend/src/mocks/handlers/voteHandler.ts b/frontend/src/mocks/handlers/voteHandler.ts index e715d24e..788c20a4 100644 --- a/frontend/src/mocks/handlers/voteHandler.ts +++ b/frontend/src/mocks/handlers/voteHandler.ts @@ -1,6 +1,7 @@ import { http, HttpResponse } from 'msw'; import BALANCE_CONTENT from '../data/balanceContent.json'; +import FINAL_RESULT from '../data/finalResult.json'; import VOTE_RESULT from '../data/roundVoteResult.json'; import { MOCK_API_URL } from '@/constants/url'; @@ -28,8 +29,13 @@ const goToNextRoundHandler = () => { return HttpResponse.json(BALANCE_CONTENT, { status: 201 }); }; +const fetchFinalResultHandler = async () => { + return HttpResponse.json(FINAL_RESULT); +}; + export const voteHandler = [ http.post(MOCK_API_URL.vote, voteBalanceContentHandler), http.get(MOCK_API_URL.roundVoteResult, fetchVoteResultHandler), http.post(MOCK_API_URL.moveNextRound, goToNextRoundHandler), + http.get(MOCK_API_URL.finalResult, fetchFinalResultHandler), ]; diff --git a/frontend/src/types/balanceContent.ts b/frontend/src/types/balanceContent.ts index f0f77949..151b87c3 100644 --- a/frontend/src/types/balanceContent.ts +++ b/frontend/src/types/balanceContent.ts @@ -13,3 +13,9 @@ export interface BalanceContent { name: string; }; } + +export interface FinalGameResult { + rank: number; + name: string; + percent: number; +} From 090e2e437454ee6019f75d6e95f14f2014fe0a55 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Wed, 24 Jul 2024 22:53:50 +0900 Subject: [PATCH 0242/1013] =?UTF-8?q?feat:=20Header=20=EB=B6=84=EA=B8=B0?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EB=B0=8F=20=EB=9D=BC=EC=9A=B4=EB=93=9C=20?= =?UTF-8?q?API=20=EB=B6=88=EB=9F=AC=EC=98=A4=EA=B8=B0=20#50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/layout/Header/Header.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/frontend/src/components/layout/Header/Header.tsx b/frontend/src/components/layout/Header/Header.tsx index 9e7b4e1b..ed623dba 100644 --- a/frontend/src/components/layout/Header/Header.tsx +++ b/frontend/src/components/layout/Header/Header.tsx @@ -1,3 +1,5 @@ +import { useLocation } from 'react-router-dom'; + import { gameTitle, headerLayout, roundText } from './Header.styled'; import SettingsIcon from '@/assets/images/settingsIcon.svg'; @@ -9,6 +11,13 @@ interface HeaderProps { const Header = ({ title }: HeaderProps) => { const { balanceContent } = useBalanceContentQuery(); + const location = useLocation(); + + const isFinalPage = location.pathname === '/game/result'; + + if (isFinalPage) { + return
; + } return (
From 27715e0ef504fa71933d9c047ccea88f178588db Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Wed, 24 Jul 2024 22:54:25 +0900 Subject: [PATCH 0243/1013] =?UTF-8?q?feat:=20=EC=B5=9C=EC=A2=85=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=20=ED=8E=98=EC=9D=B4=EC=A7=80=20UI=20?= =?UTF-8?q?=ED=8D=BC=EB=B8=94=EB=A6=AC=EC=8B=B1=20=EB=B0=8F=20API=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0=20#50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/balanceContent.ts | 4 +- .../components/GameResult/GameResult.hook.ts | 14 +++++ .../GameResult/GameResult.styled.ts | 57 ++++++++++++++++--- .../src/components/GameResult/GameResult.tsx | 45 +++++++++++++-- frontend/src/types/balanceContent.ts | 2 +- 5 files changed, 108 insertions(+), 14 deletions(-) create mode 100644 frontend/src/components/GameResult/GameResult.hook.ts diff --git a/frontend/src/apis/balanceContent.ts b/frontend/src/apis/balanceContent.ts index 88ee6da4..399ec89a 100644 --- a/frontend/src/apis/balanceContent.ts +++ b/frontend/src/apis/balanceContent.ts @@ -1,7 +1,7 @@ import fetcher from './fetcher'; import { API_URL } from '@/constants/url'; -import { BalanceContent, FinalGameResult } from '@/types/balanceContent'; +import { BalanceContent, GameResult } from '@/types/balanceContent'; import { RoundVoteResult } from '@/types/roundVoteResult'; export const fetchBalanceContent = async (roomId = 1): Promise => { @@ -46,7 +46,7 @@ export const moveNextRound = async (roomId = 1): Promise => { return data; }; -export const fetchFinalGameResult = async (roomId = 1): Promise => { +export const fetchFinalGameResult = async (roomId = 1): Promise => { const res = await fetcher.get({ url: API_URL.finalResult(roomId), }); diff --git a/frontend/src/components/GameResult/GameResult.hook.ts b/frontend/src/components/GameResult/GameResult.hook.ts new file mode 100644 index 00000000..a8d88f66 --- /dev/null +++ b/frontend/src/components/GameResult/GameResult.hook.ts @@ -0,0 +1,14 @@ +import { useQuery } from '@tanstack/react-query'; + +import { fetchFinalGameResult } from '@/apis/balanceContent'; + +const useGameResultQuery = () => { + const gameResultQuery = useQuery({ + queryKey: ['gameResult'], + queryFn: async () => await fetchFinalGameResult(), + }); + + return { ...gameResultQuery, gameResult: gameResultQuery.data }; +}; + +export { useGameResultQuery }; diff --git a/frontend/src/components/GameResult/GameResult.styled.ts b/frontend/src/components/GameResult/GameResult.styled.ts index c9c43d4d..fbb606ea 100644 --- a/frontend/src/components/GameResult/GameResult.styled.ts +++ b/frontend/src/components/GameResult/GameResult.styled.ts @@ -1,20 +1,63 @@ import { css } from '@emotion/react'; +import { Theme } from '@/styles/Theme'; + export const gameResultLayout = css` display: flex; flex-direction: column; justify-content: center; align-items: center; - gap: 6rem; - height: 40vh; + gap: 4.8rem; + width: 100%; +`; + +export const gameResultTitle = css` + ${Theme.typography.slogan}; `; -export const gameResultTitleWrapper = css` +export const rankListContainer = css` display: flex; - flex-basis: 20%; + flex-basis: 60%; + flex-direction: column; + gap: 2rem; + width: 100%; `; -export const gameResultTitle = css` - font-weight: bold; - font-size: 2.4rem; +export const rankItem = css` + display: flex; + justify-content: space-between; + align-items: center; + ${Theme.typography.headline3}; +`; + +export const rankInfoContainer = css` + display: flex; + flex-basis: 85%; + align-items: center; + gap: 1.2rem; +`; + +export const rankNumber = css` + ${Theme.typography.headline1} +`; + +export const nicknameContainer = (percent: number) => css` + display: flex; + overflow: visible; + gap: 1rem; + width: ${percent > 5 ? percent - 5 : percent}%; + height: 100%; + padding: 1.2rem; + border-radius: ${Theme.borderRadius.radius20}; + + background-color: ${Theme.color.peanut400}; + transition: all 2s; +`; + +export const rankPercent = css` + ${Theme.typography.headline3} +`; + +export const nickname = css` + min-width: 5.6rem; `; diff --git a/frontend/src/components/GameResult/GameResult.tsx b/frontend/src/components/GameResult/GameResult.tsx index cb21e4ef..a010b760 100644 --- a/frontend/src/components/GameResult/GameResult.tsx +++ b/frontend/src/components/GameResult/GameResult.tsx @@ -1,22 +1,59 @@ import { useNavigate } from 'react-router-dom'; -import { gameResultTitle, gameResultTitleWrapper, gameResultLayout } from './GameResult.styled'; +import { useGameResultQuery } from './GameResult.hook'; +import { + gameResultTitle, + gameResultLayout, + rankListContainer, + rankItem, + rankNumber, + rankInfoContainer, + nicknameContainer, + rankPercent, + nickname, +} from './GameResult.styled'; import Button from '@/components/common/Button/Button'; +import useCountAnimation from '@/hooks/useCountAnimation'; +import { GameResult } from '@/types/balanceContent'; const GameResult = () => { const navigate = useNavigate(); + const { gameResult } = useGameResultQuery(); const goToHome = () => { - navigate('/'); + navigate('/ready'); }; return ( -
-
+ <> +

게임 결과

+
+ {gameResult?.map((item) => )} +
+ ); +}; + +export default NextRoundButton; diff --git a/frontend/src/pages/RoundResultPage/RoundResultPage.tsx b/frontend/src/pages/RoundResultPage/RoundResultPage.tsx index 30876e02..eb276748 100644 --- a/frontend/src/pages/RoundResultPage/RoundResultPage.tsx +++ b/frontend/src/pages/RoundResultPage/RoundResultPage.tsx @@ -1,35 +1,14 @@ -import { useNavigate } from 'react-router-dom'; - -import { moveNextRound } from '@/apis/balanceContent'; -import Button from '@/components/common/Button/Button'; +import NextRoundButton from '@/components/common/NextRoundButton/NextRoundButton'; import Content from '@/components/layout/Content/Content'; import RoundResultTab from '@/components/RoundResultTab/RoundResultTab'; import TopicContainer from '@/components/TopicContainer/TopicContainer'; -import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; const RoundResultPage = () => { - const navigate = useNavigate(); - const { balanceContent } = useBalanceContentQuery(); - - const isLastRound = balanceContent?.currentRound === balanceContent?.totalRound; - - const goToGameResult = () => { - navigate('/game/result'); - }; - - const goToNextRound = async () => { - await moveNextRound(); - navigate('/game'); - }; - return ( - - -
-
-
- {activeTab === 'group' ? ( - - ) : ( - - )} + +
+
); }; diff --git a/frontend/src/components/TabItem/TabItem.styled.ts b/frontend/src/components/TabItem/TabItem.styled.ts new file mode 100644 index 00000000..783f0110 --- /dev/null +++ b/frontend/src/components/TabItem/TabItem.styled.ts @@ -0,0 +1,15 @@ +import { css } from '@emotion/react'; + +import { Theme } from '@/styles/Theme'; + +export const tabButtonStyle = (isActive: boolean) => css` + flex: 1; + padding: 0.8rem; + border-radius: 1.2rem 1.2rem 0 0; + + background-color: ${isActive ? Theme.color.peanut400 : Theme.color.gray}; + + color: black; + font-weight: bold; + transition: all 0.5s; +`; diff --git a/frontend/src/components/TabItem/TabItem.tsx b/frontend/src/components/TabItem/TabItem.tsx new file mode 100644 index 00000000..8387a54f --- /dev/null +++ b/frontend/src/components/TabItem/TabItem.tsx @@ -0,0 +1,23 @@ +import { tabButtonStyle } from './TabItem.styled'; + +type Tab = 'group' | 'total'; + +interface TabItemProps { + tab: Tab; + activeTab: Tab; + handleClickTab: (tab: Tab) => void; +} + +const TAB_TITLE = { + group: '그룹', + total: '전체', +} as const; + +const TabItem = ({ tab, activeTab, handleClickTab }: TabItemProps) => { + return ( + + ); +}; +export default TabItem; From 261aa4ea944560b371b1b0e5de81a5240ae48cf1 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 25 Jul 2024 18:59:18 +0900 Subject: [PATCH 0291/1013] =?UTF-8?q?refactor:=20TabContentContainer=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=B6=84=EB=A6=AC=20#50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GroupRoundResultTab.tsx | 54 --------- .../RoundResultTab/RoundResultTab.styled.ts | 101 ---------------- .../TabContentContainer.styled.ts | 108 ++++++++++++++++++ .../TabContentContainer.tsx | 72 ++++++++++++ .../TotalResultTab/TotalResultTab.tsx | 47 -------- 5 files changed, 180 insertions(+), 202 deletions(-) delete mode 100644 frontend/src/components/GroupRoundResultTab/GroupRoundResultTab.tsx create mode 100644 frontend/src/components/TabContentContainer/TabContentContainer.styled.ts create mode 100644 frontend/src/components/TabContentContainer/TabContentContainer.tsx delete mode 100644 frontend/src/components/TotalResultTab/TotalResultTab.tsx diff --git a/frontend/src/components/GroupRoundResultTab/GroupRoundResultTab.tsx b/frontend/src/components/GroupRoundResultTab/GroupRoundResultTab.tsx deleted file mode 100644 index c1152023..00000000 --- a/frontend/src/components/GroupRoundResultTab/GroupRoundResultTab.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { - barBackgroundStyle, - barStyle, - barWrapperStyle, - buttonStyle, - categoryContainer, - currentVoteButtonWrapper, - resultTextStyle, - roundVoteResultContainer, -} from '../RoundResultTab/RoundResultTab.styled'; - -import { Group } from '@/types/roundVoteResult'; - -interface GroupRoundResultTabProps { - groupRoundResult: Group; - animatedFirstPercent?: number; - animatedSecondPercent?: number; -} - -const GroupRoundResultTab = ({ - groupRoundResult, - animatedFirstPercent, - animatedSecondPercent, -}: GroupRoundResultTabProps) => { - const isBigFirstOption = groupRoundResult.firstOption.percent >= 50; - - return ( - <> -
-
- {groupRoundResult.firstOption.name} - {groupRoundResult.secondOption.name} -
-
-
- {animatedFirstPercent}% -
-
- {animatedSecondPercent}% -
-
-
- {groupRoundResult.firstOption.memberCount}명 - {groupRoundResult.secondOption.memberCount}명 -
-
-
- -
- - ); -}; - -export default GroupRoundResultTab; diff --git a/frontend/src/components/RoundResultTab/RoundResultTab.styled.ts b/frontend/src/components/RoundResultTab/RoundResultTab.styled.ts index 7de1570b..6c84c91d 100644 --- a/frontend/src/components/RoundResultTab/RoundResultTab.styled.ts +++ b/frontend/src/components/RoundResultTab/RoundResultTab.styled.ts @@ -1,7 +1,5 @@ import { css } from '@emotion/react'; -import { Theme } from '@/styles/Theme'; - export const tabLayout = css` display: flex; flex-basis: 45%; @@ -16,102 +14,3 @@ export const tabWrapperStyle = css` width: 40%; margin-left: 2.4rem; `; - -export const contentWrapperStyle = css` - display: flex; - flex-direction: column; - justify-content: space-between; - height: 100%; - padding: 2rem; - border: 0.3rem solid ${Theme.color.peanut400}; - border-radius: 0.8rem; -`; - -export const blankWrapper = css` - width: 100%; - height: 1.2rem; -`; - -export const roundVoteResultContainer = css` - display: flex; - flex-direction: column; - gap: 1rem; -`; - -export const categoryContainer = css` - display: flex; - justify-content: space-between; - - font-weight: bold; - font-size: 1.4rem; -`; - -export const barWrapperStyle = css` - display: flex; - align-items: center; - width: inherit; -`; - -export const barStyle = (percentage: number, isBigFirstOption: boolean) => css` - display: flex; - justify-content: center; - align-items: center; - - width: ${percentage}%; - height: 8vh; - border-radius: 1.6rem 0 0 1.6rem; - - background-color: ${isBigFirstOption ? Theme.color.peanut400 : Theme.color.gray}; - - color: black; - font-weight: bold; - font-size: 1.6rem; - clip-path: polygon(0 0, 100% 0, calc(100% - 10px) 100%, 0 100%); - transition: all 1s; - transform: translateX(5px); -`; - -export const barBackgroundStyle = (percentage: number, isBigFirstOption: boolean) => css` - display: flex; - justify-content: center; - align-items: center; - width: ${percentage}%; - height: 8vh; - border-radius: 0 1.6rem 1.6rem 0; - - background-color: ${isBigFirstOption ? Theme.color.gray : Theme.color.peanut400}; - - color: black; - font-weight: bold; - font-size: 1.6rem; - clip-path: polygon(10px 0, 100% 0, 100% 100%, 0 100%); - transition: all 1s; - transform: translateX(-5px); -`; - -export const resultTextStyle = (isGroupTabActive: boolean) => css` - display: flex; - visibility: ${isGroupTabActive ? 'visible' : 'hidden'}; - justify-content: space-between; - align-items: center; - height: 1.2rem; - - font-weight: bold; - font-size: 1.2rem; -`; - -export const currentVoteButtonWrapper = (isGroupTabActive: boolean) => css` - display: flex; - visibility: ${isGroupTabActive ? 'visible' : 'hidden'}; - justify-content: flex-end; - align-items: center; -`; - -export const buttonStyle = css` - color: black; - font-weight: bold; - - &:active { - opacity: 0.7; - } -`; diff --git a/frontend/src/components/TabContentContainer/TabContentContainer.styled.ts b/frontend/src/components/TabContentContainer/TabContentContainer.styled.ts new file mode 100644 index 00000000..3230b1ad --- /dev/null +++ b/frontend/src/components/TabContentContainer/TabContentContainer.styled.ts @@ -0,0 +1,108 @@ +import { css } from '@emotion/react'; + +import { Theme } from '@/styles/Theme'; + +export const contentWrapperStyle = css` + display: flex; + flex-direction: column; + justify-content: space-between; + height: 100%; + padding: 2.4rem; + border: 0.3rem solid ${Theme.color.peanut400}; + border-radius: 0.8rem; +`; + +export const alertText = (isGroupTabActive: boolean) => css` + display: flex; + visibility: ${isGroupTabActive ? 'hidden' : 'visible'}; + justify-content: center; + width: 100%; + height: 1.2rem; + + ${Theme.typography.body1} + font-weight: bold; +`; + +export const roundVoteResultContainer = css` + display: flex; + flex-direction: column; + gap: 1rem; +`; + +export const categoryContainer = css` + display: flex; + justify-content: space-between; + + font-weight: bold; + font-size: 1.4rem; +`; + +export const barWrapperStyle = css` + display: flex; + align-items: center; + width: inherit; +`; + +export const barStyle = (percentage: number, isBigFirstOption: boolean) => css` + display: flex; + justify-content: center; + align-items: center; + + width: ${percentage}%; + height: 8vh; + border-radius: 1.6rem 0 0 1.6rem; + + background-color: ${isBigFirstOption ? Theme.color.peanut400 : Theme.color.gray}; + + color: black; + font-weight: bold; + font-size: 1.6rem; + clip-path: polygon(0 0, 100% 0, calc(100% - 10px) 100%, 0 100%); + transition: all 1s; + transform: translateX(5px); +`; + +export const barBackgroundStyle = (percentage: number, isBigFirstOption: boolean) => css` + display: flex; + justify-content: center; + align-items: center; + width: ${percentage}%; + height: 8vh; + border-radius: 0 1.6rem 1.6rem 0; + + background-color: ${isBigFirstOption ? Theme.color.gray : Theme.color.peanut400}; + + color: black; + font-weight: bold; + font-size: 1.6rem; + clip-path: polygon(10px 0, 100% 0, 100% 100%, 0 100%); + transition: all 1s; + transform: translateX(-5px); +`; + +export const resultTextStyle = (isActiveGroupTab: boolean) => css` + display: flex; + visibility: ${isActiveGroupTab ? 'visible' : 'hidden'}; + justify-content: space-between; + align-items: center; + height: 1.2rem; + + font-weight: bold; + font-size: 1.2rem; +`; + +export const currentVoteButtonWrapper = (isGroupTabActive: boolean) => css` + display: flex; + visibility: ${isGroupTabActive ? 'visible' : 'hidden'}; + justify-content: flex-end; + align-items: center; +`; + +export const buttonStyle = css` + color: black; + font-weight: bold; + + &:active { + opacity: 0.7; + } +`; diff --git a/frontend/src/components/TabContentContainer/TabContentContainer.tsx b/frontend/src/components/TabContentContainer/TabContentContainer.tsx new file mode 100644 index 00000000..4ccbdc2f --- /dev/null +++ b/frontend/src/components/TabContentContainer/TabContentContainer.tsx @@ -0,0 +1,72 @@ +import { useNavigate } from 'react-router-dom'; + +import { + alertText, + barBackgroundStyle, + barStyle, + barWrapperStyle, + buttonStyle, + categoryContainer, + contentWrapperStyle, + currentVoteButtonWrapper, + resultTextStyle, + roundVoteResultContainer, +} from './TabContentContainer.styled'; + +import { Group, Total } from '@/types/roundVoteResult'; + +interface TabContentContainerProps { + isGroupTabActive: boolean; + roundResult: Group | Total; + animatedFirstPercent?: number; + animatedSecondPercent?: number; +} + +const TabContentContainer = ({ + isGroupTabActive, + roundResult, + animatedFirstPercent, + animatedSecondPercent, +}: TabContentContainerProps) => { + const navigate = useNavigate(); + + const isBigFirstOption = roundResult.firstOption.percent >= 50; + + const goToCurrentVote = () => { + navigate('/round/result/current'); + }; + return ( +
+
다른 사람들은 이렇게 생각했어요 🥜
+
+
+ {roundResult.firstOption.name} + {roundResult.secondOption.name} +
+
+ + {animatedFirstPercent}% + + + {animatedSecondPercent}% + +
+
+ {'memberCount' in roundResult.firstOption && ( + {roundResult.firstOption.memberCount}명 + )} + {'memberCount' in roundResult.secondOption && ( + {roundResult.secondOption.memberCount}명 + )} +
+
+
+ +
+
+ ); +}; + +export default TabContentContainer; diff --git a/frontend/src/components/TotalResultTab/TotalResultTab.tsx b/frontend/src/components/TotalResultTab/TotalResultTab.tsx deleted file mode 100644 index fdba2a5e..00000000 --- a/frontend/src/components/TotalResultTab/TotalResultTab.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { - barBackgroundStyle, - barStyle, - barWrapperStyle, - blankWrapper, - categoryContainer, - roundVoteResultContainer, -} from '../RoundResultTab/RoundResultTab.styled'; - -import { Total } from '@/types/roundVoteResult'; - -interface TotalResultTabProps { - totalResult: Total; - animatedTotalFirstPercent?: number; - animatedTotalSecondPercent?: number; -} - -const TotalResultTab = ({ - totalResult, - animatedTotalFirstPercent, - animatedTotalSecondPercent, -}: TotalResultTabProps) => { - const isBigFirstOption = totalResult.firstOption.percent >= 50; - - return ( - <> -
-
- {totalResult.firstOption.name} - {totalResult.secondOption.name} -
-
-
- {animatedTotalFirstPercent}% -
-
- {animatedTotalSecondPercent}% -
-
-
-
-
- - ); -}; - -export default TotalResultTab; From 347cfb53faad4cab232fc4289fe8b17f545ca819 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 25 Jul 2024 19:00:10 +0900 Subject: [PATCH 0292/1013] =?UTF-8?q?refactor:=20=EA=B2=8C=EC=9E=84=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=20=ED=8E=98=EC=9D=B4=EC=A7=80=EC=9D=98=20Fin?= =?UTF-8?q?alButton=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC=20#50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/GameResult/GameResult.tsx | 11 ++-------- .../common/FinalButton/FinalButton.tsx | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+), 9 deletions(-) create mode 100644 frontend/src/components/common/FinalButton/FinalButton.tsx diff --git a/frontend/src/components/GameResult/GameResult.tsx b/frontend/src/components/GameResult/GameResult.tsx index 33e93d38..6b6fca5f 100644 --- a/frontend/src/components/GameResult/GameResult.tsx +++ b/frontend/src/components/GameResult/GameResult.tsx @@ -1,20 +1,13 @@ -import { useNavigate } from 'react-router-dom'; - import { useGameResultQuery } from './GameResult.hook'; import { gameResultTitle, gameResultLayout, rankListContainer } from './GameResult.styled'; +import FinalButton from '../common/FinalButton/FinalButton'; import GameResultItem from '../GameResultItem/GameResultItem'; -import Button from '@/components/common/Button/Button'; import { GameResult } from '@/types/balanceContent'; const GameResult = () => { - const navigate = useNavigate(); const { gameResult } = useGameResultQuery(); - const goToHome = () => { - navigate('/ready'); - }; - return ( <>
@@ -24,7 +17,7 @@ const GameResult = () => { gameResult.map((item) => )}
-
+ ); +}; + +export default FinalButton; From adbed4225e687655a6c6f97e49ac65c752736ee6 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 25 Jul 2024 19:00:57 +0900 Subject: [PATCH 0293/1013] =?UTF-8?q?design:=20=ED=97=A4=EB=8D=94=20?= =?UTF-8?q?=EC=95=84=EC=9D=B4=EC=BD=98=20=ED=81=AC=EA=B8=B0=20=EA=B3=A0?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20=EB=B2=84=ED=8A=BC=20=ED=8C=A8=EB=94=A9?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0=20#50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/layout/Header/Header.styled.ts | 3 +++ frontend/src/styles/GlobalStyle.ts | 1 + 2 files changed, 4 insertions(+) diff --git a/frontend/src/components/layout/Header/Header.styled.ts b/frontend/src/components/layout/Header/Header.styled.ts index 010eb692..97c0f873 100644 --- a/frontend/src/components/layout/Header/Header.styled.ts +++ b/frontend/src/components/layout/Header/Header.styled.ts @@ -8,6 +8,9 @@ export const headerLayout = css` `; export const roundText = css` + width: 2.4rem; + height: 2.4rem; + font-weight: bold; font-size: 1.6rem; `; diff --git a/frontend/src/styles/GlobalStyle.ts b/frontend/src/styles/GlobalStyle.ts index 7c8fe3ef..b1fa8ce4 100644 --- a/frontend/src/styles/GlobalStyle.ts +++ b/frontend/src/styles/GlobalStyle.ts @@ -136,6 +136,7 @@ const reset = css` outline: none; background-color: inherit; cursor: pointer; + padding: 0; } `; From dfc98e47a7d3632bc55c556aeeb2343b6aae44fd Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 25 Jul 2024 19:34:04 +0900 Subject: [PATCH 0294/1013] =?UTF-8?q?refactor:=20=EB=9D=BC=EC=9A=B0?= =?UTF-8?q?=ED=8C=85=20=EA=B2=BD=EB=A1=9C=20=EC=83=81=EC=88=98=ED=99=94=20?= =?UTF-8?q?=EB=B0=8F=20=ED=97=A4=EB=8D=94=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EB=B6=84=EA=B8=B0=20=EC=B2=98=EB=A6=AC=20#50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TopicContainer/TopicContainer.tsx | 3 ++- .../src/components/layout/Header/Header.tsx | 25 ++++++++++++++----- frontend/src/constants/routes.ts | 9 +++++++ 3 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 frontend/src/constants/routes.ts diff --git a/frontend/src/components/TopicContainer/TopicContainer.tsx b/frontend/src/components/TopicContainer/TopicContainer.tsx index 666a5fd5..f84d60ac 100644 --- a/frontend/src/components/TopicContainer/TopicContainer.tsx +++ b/frontend/src/components/TopicContainer/TopicContainer.tsx @@ -2,13 +2,14 @@ import { useLocation } from 'react-router-dom'; import { categoryText, topicContainerLayout, topicText } from './TopicContainer.styled'; +import { ROUTES } from '@/constants/routes'; import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; const TopicContainer = () => { const { balanceContent } = useBalanceContentQuery(); const location = useLocation(); - const isGamePage = location.pathname === '/game'; + const isGamePage = location.pathname === ROUTES.game; return (
diff --git a/frontend/src/components/layout/Header/Header.tsx b/frontend/src/components/layout/Header/Header.tsx index ed623dba..599c81c2 100644 --- a/frontend/src/components/layout/Header/Header.tsx +++ b/frontend/src/components/layout/Header/Header.tsx @@ -2,32 +2,45 @@ import { useLocation } from 'react-router-dom'; import { gameTitle, headerLayout, roundText } from './Header.styled'; -import SettingsIcon from '@/assets/images/settingsIcon.svg'; +import { ROUTES } from '@/constants/routes'; import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; interface HeaderProps { title: string; } +// TODO: Header 분리 +// 1. 공간만 차지하는 빈 헤더 : 게임 결과 화면 +// 2. 가운데 제목만 차지하는 헤더 : 닉네임 설정 화면, 게임 대기 화면 +// 3. 좌측 상단과 가운데 제목 차지하는 헤더 : 게임 화면, 라운드 통계 화면, 라운드 투표 현황 const Header = ({ title }: HeaderProps) => { const { balanceContent } = useBalanceContentQuery(); const location = useLocation(); - const isFinalPage = location.pathname === '/game/result'; + const isRoundResultPage = location.pathname === ROUTES.roundResult; + const isFinalPage = location.pathname === ROUTES.gameResult; if (isFinalPage) { return
; } + if (isRoundResultPage) { + return ( +
+ + 투표 결과 + +
+ ); + } + return (
- {balanceContent?.currentRound}/{balanceContent?.totalRound} + {balanceContent ? `${balanceContent.currentRound}/${balanceContent.totalRound}` : '1/5'} {title} - +
); }; diff --git a/frontend/src/constants/routes.ts b/frontend/src/constants/routes.ts new file mode 100644 index 00000000..4c33a356 --- /dev/null +++ b/frontend/src/constants/routes.ts @@ -0,0 +1,9 @@ +export const ROUTES = { + main: '/', + nickname: '/nickname', + ready: '/ready', + game: '/game', + roundResult: '/round/result', + roundResultVote: '/round/result/vote', + gameResult: '/game/result', +} as const; From 7a2deb552bd29193b32988027ba465808fc6f7a9 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 25 Jul 2024 20:10:49 +0900 Subject: [PATCH 0295/1013] =?UTF-8?q?fix:=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=EB=AA=85=EA=B3=BC=20=ED=83=80=EC=9E=85=EB=AA=85?= =?UTF-8?q?=EC=9D=B4=20=EA=B0=99=EC=95=84=EC=84=9C=20=EC=83=9D=EA=B8=B0?= =?UTF-8?q?=EB=8A=94=20=EB=B9=8C=EB=93=9C=20=EC=98=A4=EB=A5=98=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0=20#50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/balanceContent.ts | 4 ++-- frontend/src/components/GameResult/GameResult.tsx | 4 +--- .../src/components/GameResultItem/GameResultItem.tsx | 12 ++++++------ frontend/src/types/balanceContent.ts | 2 +- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/frontend/src/apis/balanceContent.ts b/frontend/src/apis/balanceContent.ts index 399ec89a..6f434d32 100644 --- a/frontend/src/apis/balanceContent.ts +++ b/frontend/src/apis/balanceContent.ts @@ -1,7 +1,7 @@ import fetcher from './fetcher'; import { API_URL } from '@/constants/url'; -import { BalanceContent, GameResult } from '@/types/balanceContent'; +import { BalanceContent, GameFinalResult } from '@/types/balanceContent'; import { RoundVoteResult } from '@/types/roundVoteResult'; export const fetchBalanceContent = async (roomId = 1): Promise => { @@ -46,7 +46,7 @@ export const moveNextRound = async (roomId = 1): Promise => { return data; }; -export const fetchFinalGameResult = async (roomId = 1): Promise => { +export const fetchFinalGameResult = async (roomId = 1): Promise => { const res = await fetcher.get({ url: API_URL.finalResult(roomId), }); diff --git a/frontend/src/components/GameResult/GameResult.tsx b/frontend/src/components/GameResult/GameResult.tsx index 6b6fca5f..1ad6f85e 100644 --- a/frontend/src/components/GameResult/GameResult.tsx +++ b/frontend/src/components/GameResult/GameResult.tsx @@ -3,8 +3,6 @@ import { gameResultTitle, gameResultLayout, rankListContainer } from './GameResu import FinalButton from '../common/FinalButton/FinalButton'; import GameResultItem from '../GameResultItem/GameResultItem'; -import { GameResult } from '@/types/balanceContent'; - const GameResult = () => { const { gameResult } = useGameResultQuery(); @@ -14,7 +12,7 @@ const GameResult = () => {

게임 결과

{gameResult && - gameResult.map((item) => )} + gameResult.map((item) => )}
diff --git a/frontend/src/components/GameResultItem/GameResultItem.tsx b/frontend/src/components/GameResultItem/GameResultItem.tsx index 66d249aa..dd8b2c68 100644 --- a/frontend/src/components/GameResultItem/GameResultItem.tsx +++ b/frontend/src/components/GameResultItem/GameResultItem.tsx @@ -8,24 +8,24 @@ import { } from './GameResultItem.styled'; import useCountAnimation from '@/hooks/useCountAnimation'; -import { GameResult } from '@/types/balanceContent'; +import { GameFinalResult } from '@/types/balanceContent'; interface GameResultItemProps { - gameResult: GameResult; + gameFinalResult: GameFinalResult; } -const GameResultItem = ({ gameResult }: GameResultItemProps) => { +const GameResultItem = ({ gameFinalResult }: GameResultItemProps) => { const animatedRankPercent = useCountAnimation({ - target: gameResult.percent, + target: gameFinalResult.percent, duration: 3000, }); return (
- {gameResult.rank} + {gameFinalResult.rank}
🥜 - {gameResult.name} + {gameFinalResult.name}
{animatedRankPercent}% diff --git a/frontend/src/types/balanceContent.ts b/frontend/src/types/balanceContent.ts index 5dfa6dc7..71ea8ddf 100644 --- a/frontend/src/types/balanceContent.ts +++ b/frontend/src/types/balanceContent.ts @@ -14,7 +14,7 @@ export interface BalanceContent { }; } -export interface GameResult { +export interface GameFinalResult { rank: number; name: string; percent: number; From 4922e3fad4707660f2a81f32902e6cc6d633061e Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 25 Jul 2024 20:36:58 +0900 Subject: [PATCH 0296/1013] =?UTF-8?q?feat:=20=EB=8B=A4=EC=9D=8C=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B4=EB=93=9C=EB=A1=9C=20=EB=84=98=EC=96=B4?= =?UTF-8?q?=EA=B0=80=EB=8A=94=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B5=AC=ED=98=84=20#63?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ddangkong/domain/balance/room/Room.java | 17 ++++++- .../domain/balance/room/RoomTest.java | 50 +++++++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java diff --git a/backend/src/main/java/ddangkong/domain/balance/room/Room.java b/backend/src/main/java/ddangkong/domain/balance/room/Room.java index 7f0daa5a..84c99cc9 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/Room.java @@ -1,5 +1,6 @@ package ddangkong.domain.balance.room; +import ddangkong.exception.BadRequestException; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -12,7 +13,7 @@ public class Room { private static final int DEFAULT_TOTAL_ROUND = 5; - private static final int DEFAULT_CURRENT_ROUND = 1; + private static final int START_ROUND = 1; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -22,5 +23,17 @@ public class Room { private int totalRound = DEFAULT_TOTAL_ROUND; @Column(nullable = false) - private int currentRound = DEFAULT_CURRENT_ROUND; + private int currentRound = START_ROUND; + + public void moveToNextRound() { + if (canMoveToNextRound()) { + currentRound++; + return; + } + throw new BadRequestException("마지막 라운드입니다."); + } + + private boolean canMoveToNextRound() { + return currentRound < totalRound; + } } diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java new file mode 100644 index 00000000..cb577350 --- /dev/null +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java @@ -0,0 +1,50 @@ +package ddangkong.domain.balance.room; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import ddangkong.exception.BadRequestException; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +class RoomTest { + + @Nested + class 다음_라운드로_이동 { + + private static final int START_ROUND = 1; + private static final int TOTAL_ROUND = 5; + + @Test + void 다음_라운드로_이동할_수_있다() { + // given + Room room = new Room(); + int currentRound = room.getCurrentRound(); + int expectedRound = currentRound + 1; + + // when + room.moveToNextRound(); + + // then + assertThat(room.getCurrentRound()).isEqualTo(expectedRound); + } + + @Test + void 마지막_라운드_일_경우_예외를_던진다() { + // given + Room room = new Room(); + goToFinalRound(room); + + // when & then + assertThatThrownBy(() -> room.moveToNextRound()) + .isInstanceOf(BadRequestException.class) + .hasMessage("마지막 라운드입니다."); + } + + private void goToFinalRound(Room room) { + for (int round = START_ROUND; round < TOTAL_ROUND; round++) { + room.moveToNextRound(); + } + } + } +} From eeabec4fb2910cf966336db0189b6dd2a52d5546 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 25 Jul 2024 20:38:30 +0900 Subject: [PATCH 0297/1013] =?UTF-8?q?feat:=20=EB=8B=A4=EC=9D=8C=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B4=EB=93=9C=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EB=B9=84=EC=A6=88=EB=8B=88=EC=8A=A4=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84=20#63?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/balance/room/RoomService.java | 60 ++++++++++++++++--- .../service/balance/room/RoomServiceTest.java | 54 ++++++++++++++--- backend/src/test/resources/init-test.sql | 10 +++- 3 files changed, 107 insertions(+), 17 deletions(-) diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index 4fe29816..e2297b44 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -1,13 +1,21 @@ package ddangkong.service.balance.room; +import ddangkong.controller.balance.content.dto.BalanceContentResponse; import ddangkong.controller.balance.member.dto.MemberResponse; import ddangkong.controller.balance.room.dto.RoomJoinResponse; import ddangkong.controller.balance.room.dto.RoomMemberResponse; import ddangkong.controller.balance.room.dto.RoomMembersResponse; +import ddangkong.domain.balance.content.BalanceContent; +import ddangkong.domain.balance.option.BalanceOption; +import ddangkong.domain.balance.option.BalanceOptionRepository; import ddangkong.domain.balance.room.Room; +import ddangkong.domain.balance.room.RoomContent; +import ddangkong.domain.balance.room.RoomContentRepository; import ddangkong.domain.balance.room.RoomRepository; import ddangkong.domain.member.Member; import ddangkong.domain.member.MemberRepository; +import ddangkong.exception.BadRequestException; +import ddangkong.exception.InternalServerException; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -17,10 +25,27 @@ @RequiredArgsConstructor public class RoomService { + private static final int BALANCE_OPTION_SIZE = 2; + private final RoomRepository roomRepository; private final MemberRepository memberRepository; + private final RoomContentRepository roomContentRepository; + + private final BalanceOptionRepository balanceOptionRepository; + + @Transactional(readOnly = true) + public RoomMembersResponse findAllRoomMember(Long roomId) { + Room room = roomRepository.getById(roomId); + + List response = memberRepository.findByRoom(room) + .stream() + .map(RoomMemberResponse::new) + .toList(); + return new RoomMembersResponse(response); + } + @Transactional public RoomJoinResponse createRoom(String nickname) { Room room = roomRepository.save(new Room()); @@ -35,14 +60,35 @@ public RoomJoinResponse joinRoom(String nickname, Long roomId) { return new RoomJoinResponse(room.getId(), new MemberResponse(member)); } - @Transactional(readOnly = true) - public RoomMembersResponse findAllRoomMember(Long roomId) { + @Transactional + public BalanceContentResponse moveToNextRound(Long roomId) { Room room = roomRepository.getById(roomId); + room.moveToNextRound(); - List response = memberRepository.findByRoom(room) - .stream() - .map(RoomMemberResponse::new) - .toList(); - return new RoomMembersResponse(response); + RoomContent roomContent = findCurrentRoomContent(roomId); + List balanceOptions = findBalanceOptions(roomContent.getBalanceContent()); + return BalanceContentResponse.builder() + .roomContent(roomContent) + .firstOption(balanceOptions.get(0)) + .secondOption(balanceOptions.get(1)) + .build(); + } + + private RoomContent findCurrentRoomContent(Long roomId) { + Room room = roomRepository.getById(roomId); + return roomContentRepository.findByRoomAndRound(room, room.getCurrentRound()) + .orElseThrow(() -> new BadRequestException("해당 방의 현재 진행중인 질문이 존재하지 않습니다.")); + } + + private List findBalanceOptions(BalanceContent balanceContent) { + List balanceOptions = balanceOptionRepository.findByBalanceContent(balanceContent); + validateBalanceOptions(balanceOptions); + return balanceOptions; + } + + private void validateBalanceOptions(List balanceOptions) { + if (balanceOptions.size() != BALANCE_OPTION_SIZE) { + throw new InternalServerException("밸런스 게임의 선택지가 %d개입니다".formatted(balanceOptions.size())); + } } } diff --git a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java index 17460189..f9132ba6 100644 --- a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java @@ -3,8 +3,11 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import ddangkong.controller.balance.content.dto.BalanceContentResponse; import ddangkong.controller.balance.member.dto.MemberResponse; +import ddangkong.controller.balance.option.dto.BalanceOptionResponse; import ddangkong.controller.balance.room.dto.RoomJoinResponse; +import ddangkong.domain.balance.content.Category; import ddangkong.exception.BadRequestException; import ddangkong.service.BaseServiceTest; import ddangkong.controller.balance.room.dto.RoomMembersResponse; @@ -18,6 +21,22 @@ class RoomServiceTest extends BaseServiceTest { @Autowired private RoomService roomService; + @Nested + class 게임_방_전체_멤버_조회 { + + @Test + void 게임_방_전쳬_멤버_조회() { + // given + Long roomId = 1L; + + // when + RoomMembersResponse actual = roomService.findAllRoomMember(roomId); + + // then + Assertions.assertThat(actual.members()).hasSize(4); + } + } + @Nested class 방_생성 { @@ -67,18 +86,39 @@ class 방_참여 { } @Nested - class 게임_방_전체_멤버_조회 { + class 다음_라운드로_이동 { - @Test - void 게임_방_전쳬_멤버_조회() { - // given - Long roomId = 1L; + private static final Long PROGRESS_ROOM_ID = 1L; + private static final Long NOT_EXIST_ROOM_ID = 3L; + private static final Long NOT_PROGRESSED_ROOM_ID = 2L; + private static final BalanceContentResponse BALANCE_CONTENT_RESPONSE = new BalanceContentResponse( + 3L, Category.EXAMPLE, 5, 3, "다음 중 여행가고 싶은 곳은?", + new BalanceOptionResponse(5L, "산"), + new BalanceOptionResponse(6L, "바다")); + @Test + void 다음_라운드로_넘어갈_수_있다() { // when - RoomMembersResponse actual = roomService.findAllRoomMember(roomId); + BalanceContentResponse actual = roomService.moveToNextRound(PROGRESS_ROOM_ID); // then - Assertions.assertThat(actual.members()).hasSize(4); + assertThat(actual).isEqualTo(BALANCE_CONTENT_RESPONSE); + } + + @Test + void 방이_없을_경우_예외를_던진다() { + // when & then + assertThatThrownBy(() -> roomService.moveToNextRound(NOT_EXIST_ROOM_ID)) + .isInstanceOf(BadRequestException.class) + .hasMessage("해당 방이 존재하지 않습니다."); + } + + @Test + void 방의_현재_라운드의_질문이_없을_경우_예외를_던진다() { + // when & then + assertThatThrownBy(() -> roomService.moveToNextRound(NOT_PROGRESSED_ROOM_ID)) + .isInstanceOf(BadRequestException.class) + .hasMessage("해당 방의 현재 진행중인 질문이 존재하지 않습니다."); } } } diff --git a/backend/src/test/resources/init-test.sql b/backend/src/test/resources/init-test.sql index a259fc40..a2ca4364 100644 --- a/backend/src/test/resources/init-test.sql +++ b/backend/src/test/resources/init-test.sql @@ -10,17 +10,21 @@ VALUES ('mohamedeu al katan', 1, true), INSERT INTO balance_content (category, name) VALUES ('EXAMPLE', '민초 vs 반민초'), - ('EXAMPLE', '월 200 백수 vs 월 500 직장인'); + ('EXAMPLE', '월 200 백수 vs 월 500 직장인'), + ('EXAMPLE', '다음 중 여행가고 싶은 곳은?'); INSERT INTO room_content (room_id, balance_content_id, round, created_at) VALUES (1, 2, 1, '2024-07-18 19:50:00.000'), - (1, 1, 2, '2024-07-18 20:00:00.000'); + (1, 1, 2, '2024-07-18 20:00:00.000'), + (1, 3, 3, '2024-07-18 20:00:00.000'); INSERT INTO balance_option (name, balance_content_id) VALUES ('민초', 1), ('반민초', 1), ('월 200 백수', 2), - ('월 200 직장인', 2); + ('월 200 직장인', 2), + ('산', 3), + ('바다', 3); INSERT INTO balance_vote (balance_option_id, member_id) VALUES (4, 1), From 61388976111b157ad8469a106d42a1c15831805e Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 25 Jul 2024 20:39:09 +0900 Subject: [PATCH 0298/1013] =?UTF-8?q?feat:=20=EB=8B=A4=EC=9D=8C=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B4=EB=93=9C=EB=A1=9C=20=EB=84=98=EC=96=B4?= =?UTF-8?q?=EA=B0=80=EB=8A=94=20API=20=EA=B5=AC=ED=98=84=20#63?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../balance/room/RoomController.java | 19 +++++-- .../balance/room/RoomControllerTest.java | 56 +++++++++++++++---- 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java index 05bf0ed0..2deb5ddd 100644 --- a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java +++ b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java @@ -1,5 +1,6 @@ package ddangkong.controller.balance.room; +import ddangkong.controller.balance.content.dto.BalanceContentResponse; import ddangkong.controller.balance.room.dto.RoomJoinRequest; import ddangkong.controller.balance.room.dto.RoomJoinResponse; import ddangkong.controller.balance.room.dto.RoomMembersResponse; @@ -26,9 +27,16 @@ public class RoomController { private final RoomService roomService; + @GetMapping("/balances/rooms/{roomId}/members") + public ResponseEntity getAllBalanceGameRoomMember(@Positive @PathVariable Long roomId) { + RoomMembersResponse response = roomService.findAllRoomMember(roomId); + + return ResponseEntity.ok(response); + } + @ResponseStatus(HttpStatus.CREATED) @PostMapping("/balances/rooms") - public RoomJoinResponse creatRoom(@Valid @RequestBody RoomJoinRequest request) { + public RoomJoinResponse createRoom(@Valid @RequestBody RoomJoinRequest request) { return roomService.createRoom(request.nickname()); } @@ -38,10 +46,9 @@ public RoomJoinResponse joinRoom(@PathVariable @Positive Long roomId, @Valid @Re return roomService.joinRoom(request.nickname(), roomId); } - @GetMapping("/balances/rooms/{roomId}/members") - public ResponseEntity getAllBalanceGameRoomMember(@Positive @PathVariable Long roomId) { - RoomMembersResponse response = roomService.findAllRoomMember(roomId); - - return ResponseEntity.ok(response); + @ResponseStatus(HttpStatus.CREATED) + @PostMapping("/balances/rooms/{roomId}/contents") + public BalanceContentResponse moveToNextRound(@PathVariable @Positive Long roomId) { + return roomService.moveToNextRound(roomId); } } diff --git a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java index 4dd0c029..fb88a2e4 100644 --- a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java @@ -3,8 +3,11 @@ import static org.assertj.core.api.Assertions.assertThat; import ddangkong.controller.BaseControllerTest; +import ddangkong.controller.balance.content.dto.BalanceContentResponse; +import ddangkong.controller.balance.option.dto.BalanceOptionResponse; import ddangkong.controller.balance.room.dto.RoomJoinResponse; import ddangkong.controller.balance.room.dto.RoomMembersResponse; +import ddangkong.domain.balance.content.Category; import io.restassured.RestAssured; import io.restassured.http.ContentType; import java.util.HashMap; @@ -15,6 +18,23 @@ class RoomControllerTest extends BaseControllerTest { + @Nested + class 밸런스_게임_방_전체_멤버_조회 { + + @Test + void 게임_방_전체_멤버_조회() { + //when + RoomMembersResponse actual = RestAssured.given() + .when().get("/api/balances/rooms/1/members") + .then().contentType(ContentType.JSON).log().all() + .statusCode(200) + .extract().as(RoomMembersResponse.class); + + //then + Assertions.assertThat(actual.members()).hasSize(4); + } + } + @Nested class 방_생성 { @@ -97,19 +117,35 @@ class 방_참가 { } @Nested - class 밸런스_게임_방_전체_멤버_조회 { + class 다음_라운드_진행 { + + private static final BalanceContentResponse EXPECTED_RESPONSE = new BalanceContentResponse( + 3L, Category.EXAMPLE, 5, 3, "다음 중 여행가고 싶은 곳은?", + new BalanceOptionResponse(5L, "산"), + new BalanceOptionResponse(6L, "바다")); @Test - void 게임_방_전체_멤버_조회() { - //when - RoomMembersResponse actual = RestAssured.given() - .when().get("/api/balances/rooms/1/members") - .then().contentType(ContentType.JSON).log().all() - .statusCode(200) - .extract().as(RoomMembersResponse.class); + void 다음_라운드로_진행할_수_있다() { + // when + BalanceContentResponse actual = RestAssured.given().log().all() + .pathParam("roomId", 1L) + .when().post("/api/balances/rooms/{roomId}/contents") + .then().log().all() + .statusCode(201) + .extract().as(BalanceContentResponse.class); - //then - Assertions.assertThat(actual.members()).hasSize(4); + // then + assertThat(actual).isEqualTo(EXPECTED_RESPONSE); + } + + @Test + void 방의_식별자가_음수인_경우_예외를_던진다() { + // when & then + RestAssured.given().log().all() + .pathParam("roomId", -1L) + .when().post("/api/balances/rooms/{roomId}/contents") + .then().log().all() + .statusCode(400); } } } From 074de80df99e8f92de320562d835db051195f335 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 25 Jul 2024 20:48:28 +0900 Subject: [PATCH 0299/1013] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=EC=BD=94=EB=93=9C=20=EC=9D=BC=EB=B6=80=20Map=EC=9D=98=20?= =?UTF-8?q?=EC=A0=95=EC=A0=81=20=ED=8C=A9=ED=86=A0=EB=A6=AC=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=82=AC=EC=9A=A9,=20=EA=B0=9C=ED=96=89?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/balance/room/RoomControllerTest.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java index fb88a2e4..54a278ae 100644 --- a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java @@ -82,8 +82,7 @@ class 방_참가 { void 방에_참가할_수_있다() { // given String nickname = "참가자"; - Map body = new HashMap<>(); - body.put("nickname", nickname); + Map body = Map.of("nickname", nickname); // when & then RestAssured.given().log().all() @@ -99,8 +98,7 @@ class 방_참가 { void 방에_참가한_멤버는_방장이_아니다() { // given String nickname = "참가자"; - Map body = new HashMap<>(); - body.put("nickname", nickname); + Map body = Map.of("nickname", nickname); // when & then RoomJoinResponse actual = RestAssured.given().log().all() @@ -112,7 +110,6 @@ class 방_참가 { .extract().as(RoomJoinResponse.class); assertThat(actual.member().isMaster()).isFalse(); - } } From 8defa35fcb6e810434a88b0f435b5f36287d8221 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 25 Jul 2024 20:50:29 +0900 Subject: [PATCH 0300/1013] =?UTF-8?q?style:=20=EC=B9=B4=EC=9A=B4=ED=8C=85?= =?UTF-8?q?=20=EC=95=A0=EB=8B=88=EB=A9=94=EC=9D=B4=EC=85=98=20=EC=A3=BC?= =?UTF-8?q?=EC=84=9D=20=EC=B6=94=EA=B0=80=20#50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useCountAnimation.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/src/hooks/useCountAnimation.ts b/frontend/src/hooks/useCountAnimation.ts index 3a092158..e638e270 100644 --- a/frontend/src/hooks/useCountAnimation.ts +++ b/frontend/src/hooks/useCountAnimation.ts @@ -11,13 +11,15 @@ interface UseCountAnimationProps { duration?: number; } +// start에서 target으로 숫자 카운팅되는 애니메이션 커스텀 훅 const useCountAnimation = ({ target, start = 50, duration = 2000 }: UseCountAnimationProps) => { const [count, setCount] = useState(start); const frameRate = 500 / 60; const totalFrame = Math.round(duration / frameRate); useEffect(() => { - if (typeof target === 'undefined' || target === start) return; // target 값을 API로 불러올 경우 초기값이 애니메이션에 반영되므로 예외처리 + // target 값을 API로 불러올 경우 초기값이 애니메이션에 반영되므로 예외처리 + if (typeof target === 'undefined' || target === start) return; let currentNumber = start; const counter = setInterval(() => { const progress = easeOutRate(++currentNumber / totalFrame); From 04ffc25aa5053c1a32843579e4ef7fa9d53f6e79 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 25 Jul 2024 21:02:30 +0900 Subject: [PATCH 0301/1013] =?UTF-8?q?refactor:=20=EB=9D=BC=EC=9A=B4?= =?UTF-8?q?=EB=93=9C=20=ED=86=B5=EA=B3=84=20=ED=99=94=EB=A9=B4=20=ED=83=AD?= =?UTF-8?q?=EA=B3=BC=20TabItem=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8?= =?UTF-8?q?=EB=AA=85=20=EC=88=98=EC=A0=95=20#50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RoundResultTab/RoundResultTab.styled.ts | 21 ++++---- .../RoundResultTab/RoundResultTab.tsx | 53 ++++++------------- .../RoundVoteContainer.hook.ts} | 0 .../RoundVoteContainer.styled.ts | 16 ++++++ .../RoundVoteContainer/RoundVoteContainer.tsx | 46 ++++++++++++++++ .../src/components/TabItem/TabItem.styled.ts | 15 ------ frontend/src/components/TabItem/TabItem.tsx | 23 -------- .../pages/RoundResultPage/RoundResultPage.tsx | 4 +- 8 files changed, 89 insertions(+), 89 deletions(-) rename frontend/src/components/{RoundResultTab/RoundResultTab.hook.ts => RoundVoteContainer/RoundVoteContainer.hook.ts} (100%) create mode 100644 frontend/src/components/RoundVoteContainer/RoundVoteContainer.styled.ts create mode 100644 frontend/src/components/RoundVoteContainer/RoundVoteContainer.tsx delete mode 100644 frontend/src/components/TabItem/TabItem.styled.ts delete mode 100644 frontend/src/components/TabItem/TabItem.tsx diff --git a/frontend/src/components/RoundResultTab/RoundResultTab.styled.ts b/frontend/src/components/RoundResultTab/RoundResultTab.styled.ts index 6c84c91d..783f0110 100644 --- a/frontend/src/components/RoundResultTab/RoundResultTab.styled.ts +++ b/frontend/src/components/RoundResultTab/RoundResultTab.styled.ts @@ -1,16 +1,15 @@ import { css } from '@emotion/react'; -export const tabLayout = css` - display: flex; - flex-basis: 45%; - flex-direction: column; - width: 100%; +import { Theme } from '@/styles/Theme'; - transition: all 1s; -`; +export const tabButtonStyle = (isActive: boolean) => css` + flex: 1; + padding: 0.8rem; + border-radius: 1.2rem 1.2rem 0 0; + + background-color: ${isActive ? Theme.color.peanut400 : Theme.color.gray}; -export const tabWrapperStyle = css` - display: flex; - width: 40%; - margin-left: 2.4rem; + color: black; + font-weight: bold; + transition: all 0.5s; `; diff --git a/frontend/src/components/RoundResultTab/RoundResultTab.tsx b/frontend/src/components/RoundResultTab/RoundResultTab.tsx index 57035ce4..2a4823a0 100644 --- a/frontend/src/components/RoundResultTab/RoundResultTab.tsx +++ b/frontend/src/components/RoundResultTab/RoundResultTab.tsx @@ -1,46 +1,23 @@ -import { useState } from 'react'; +import { tabButtonStyle } from './RoundResultTab.styled'; -import { useTotalCountAnimation } from './RoundResultTab.hook'; -import { tabLayout, tabWrapperStyle } from './RoundResultTab.styled'; -import TabContentContainer from '../TabContentContainer/TabContentContainer'; -import TabItem from '../TabItem/TabItem'; +type TabTitle = 'group' | 'total'; -import useRoundVoteResultQuery from '@/hooks/useRoundVoteResultQuery'; +interface RoundResultTabProps { + tab: TabTitle; + activeTab: TabTitle; + handleClickTab: (tab: TabTitle) => void; +} -const RoundResultTab = () => { - const [activeTab, setActiveTab] = useState<'group' | 'total'>('group'); - const isGroupTabActive = activeTab === 'group'; - - const { groupRoundResult, totalResult } = useRoundVoteResultQuery(); - const { - animatedFirstPercent, - animatedSecondPercent, - animatedTotalFirstPercent, - animatedTotalSecondPercent, - } = useTotalCountAnimation(groupRoundResult, totalResult); - - const handleClickTab = (clickedTab: 'group' | 'total') => { - setActiveTab(clickedTab); - }; - - if (!groupRoundResult || !totalResult) return
데이터가 없습니다
; +const TAB_TITLE = { + group: '그룹', + total: '전체', +} as const; +const RoundResultTab = ({ tab, activeTab, handleClickTab }: RoundResultTabProps) => { return ( -
-
- - -
- -
+ ); }; - export default RoundResultTab; diff --git a/frontend/src/components/RoundResultTab/RoundResultTab.hook.ts b/frontend/src/components/RoundVoteContainer/RoundVoteContainer.hook.ts similarity index 100% rename from frontend/src/components/RoundResultTab/RoundResultTab.hook.ts rename to frontend/src/components/RoundVoteContainer/RoundVoteContainer.hook.ts diff --git a/frontend/src/components/RoundVoteContainer/RoundVoteContainer.styled.ts b/frontend/src/components/RoundVoteContainer/RoundVoteContainer.styled.ts new file mode 100644 index 00000000..6c84c91d --- /dev/null +++ b/frontend/src/components/RoundVoteContainer/RoundVoteContainer.styled.ts @@ -0,0 +1,16 @@ +import { css } from '@emotion/react'; + +export const tabLayout = css` + display: flex; + flex-basis: 45%; + flex-direction: column; + width: 100%; + + transition: all 1s; +`; + +export const tabWrapperStyle = css` + display: flex; + width: 40%; + margin-left: 2.4rem; +`; diff --git a/frontend/src/components/RoundVoteContainer/RoundVoteContainer.tsx b/frontend/src/components/RoundVoteContainer/RoundVoteContainer.tsx new file mode 100644 index 00000000..1cd0a3fb --- /dev/null +++ b/frontend/src/components/RoundVoteContainer/RoundVoteContainer.tsx @@ -0,0 +1,46 @@ +import { useState } from 'react'; + +import { useTotalCountAnimation } from './RoundVoteContainer.hook'; +import { tabLayout, tabWrapperStyle } from './RoundVoteContainer.styled'; +import RoundResultTab from '../RoundResultTab/RoundResultTab'; +import TabContentContainer from '../TabContentContainer/TabContentContainer'; + +import useRoundVoteResultQuery from '@/hooks/useRoundVoteResultQuery'; + +const RoundVoteContainer = () => { + const [activeTab, setActiveTab] = useState<'group' | 'total'>('group'); + const isGroupTabActive = activeTab === 'group'; + + const { groupRoundResult, totalResult } = useRoundVoteResultQuery(); + const { + animatedFirstPercent, + animatedSecondPercent, + animatedTotalFirstPercent, + animatedTotalSecondPercent, + } = useTotalCountAnimation(groupRoundResult, totalResult); + + const handleClickTab = (clickedTab: 'group' | 'total') => { + setActiveTab(clickedTab); + }; + + if (!groupRoundResult || !totalResult) return
데이터가 없습니다
; + + return ( +
+
+ + +
+ +
+ ); +}; + +export default RoundVoteContainer; diff --git a/frontend/src/components/TabItem/TabItem.styled.ts b/frontend/src/components/TabItem/TabItem.styled.ts deleted file mode 100644 index 783f0110..00000000 --- a/frontend/src/components/TabItem/TabItem.styled.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { css } from '@emotion/react'; - -import { Theme } from '@/styles/Theme'; - -export const tabButtonStyle = (isActive: boolean) => css` - flex: 1; - padding: 0.8rem; - border-radius: 1.2rem 1.2rem 0 0; - - background-color: ${isActive ? Theme.color.peanut400 : Theme.color.gray}; - - color: black; - font-weight: bold; - transition: all 0.5s; -`; diff --git a/frontend/src/components/TabItem/TabItem.tsx b/frontend/src/components/TabItem/TabItem.tsx deleted file mode 100644 index 8387a54f..00000000 --- a/frontend/src/components/TabItem/TabItem.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { tabButtonStyle } from './TabItem.styled'; - -type Tab = 'group' | 'total'; - -interface TabItemProps { - tab: Tab; - activeTab: Tab; - handleClickTab: (tab: Tab) => void; -} - -const TAB_TITLE = { - group: '그룹', - total: '전체', -} as const; - -const TabItem = ({ tab, activeTab, handleClickTab }: TabItemProps) => { - return ( - - ); -}; -export default TabItem; diff --git a/frontend/src/pages/RoundResultPage/RoundResultPage.tsx b/frontend/src/pages/RoundResultPage/RoundResultPage.tsx index eb276748..eef18516 100644 --- a/frontend/src/pages/RoundResultPage/RoundResultPage.tsx +++ b/frontend/src/pages/RoundResultPage/RoundResultPage.tsx @@ -1,13 +1,13 @@ import NextRoundButton from '@/components/common/NextRoundButton/NextRoundButton'; import Content from '@/components/layout/Content/Content'; -import RoundResultTab from '@/components/RoundResultTab/RoundResultTab'; +import RoundVoteContainer from '@/components/RoundVoteContainer/RoundVoteContainer'; import TopicContainer from '@/components/TopicContainer/TopicContainer'; const RoundResultPage = () => { return ( - + ); From 96c2b678380876f8ca13e55db28f07198dd88741 Mon Sep 17 00:00:00 2001 From: jhon3242 Date: Thu, 25 Jul 2024 23:47:01 +0900 Subject: [PATCH 0302/1013] =?UTF-8?q?feat:=20=EC=84=A0=ED=83=9D=EC=A7=80?= =?UTF-8?q?=EB=B3=84=20=ED=88=AC=ED=91=9C=20=EA=B2=B0=EA=B3=BC=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 특정 방 사용자들의 투표 결과를 가져온다. - 특정 선택지에 대한 전체 결과를 가져온다. --- .../dto/BalanceContentGroupResponse.java | 9 ++ .../dto/BalanceContentTotalResponse.java | 9 ++ .../dto/BalanceOptionGroupResponse.java | 26 ++++++ .../dto/BalanceOptionTotalResponse.java | 17 ++++ .../balance/vote/BalanceVoteController.java | 8 ++ .../vote/dto/BalanceVoteResultResponse.java | 11 +++ .../content/BalanceContentRepository.java | 13 +++ .../option/BalanceOptionRepository.java | 2 +- .../domain/balance/vote/BalanceVote.java | 4 + .../balance/vote/BalanceVoteRepository.java | 7 ++ .../domain/member/MemberRepository.java | 2 +- .../content/BalanceContentService.java | 2 +- .../service/balance/room/RoomService.java | 2 +- .../balance/vote/BalanceVoteService.java | 88 +++++++++++++++++++ .../content/BalanceContentServiceTest.java | 2 +- .../service/balance/room/RoomServiceTest.java | 6 +- .../balance/vote/BalanceVoteServiceTest.java | 44 ++++++++++ backend/src/test/resources/init-test.sql | 13 ++- 18 files changed, 254 insertions(+), 11 deletions(-) create mode 100644 backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentGroupResponse.java create mode 100644 backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentTotalResponse.java create mode 100644 backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionGroupResponse.java create mode 100644 backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionTotalResponse.java create mode 100644 backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteResultResponse.java create mode 100644 backend/src/main/java/ddangkong/domain/balance/content/BalanceContentRepository.java diff --git a/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentGroupResponse.java b/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentGroupResponse.java new file mode 100644 index 00000000..3afbc0c9 --- /dev/null +++ b/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentGroupResponse.java @@ -0,0 +1,9 @@ +package ddangkong.controller.balance.content.dto; + +import ddangkong.controller.balance.option.dto.BalanceOptionGroupResponse; + +public record BalanceContentGroupResponse( + BalanceOptionGroupResponse firstOption, + BalanceOptionGroupResponse secondOption +) { +} diff --git a/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentTotalResponse.java b/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentTotalResponse.java new file mode 100644 index 00000000..76fe49a6 --- /dev/null +++ b/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentTotalResponse.java @@ -0,0 +1,9 @@ +package ddangkong.controller.balance.content.dto; + +import ddangkong.controller.balance.option.dto.BalanceOptionTotalResponse; + +public record BalanceContentTotalResponse( + BalanceOptionTotalResponse firstOption, + BalanceOptionTotalResponse secondOption +) { +} diff --git a/backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionGroupResponse.java b/backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionGroupResponse.java new file mode 100644 index 00000000..ee38a279 --- /dev/null +++ b/backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionGroupResponse.java @@ -0,0 +1,26 @@ +package ddangkong.controller.balance.option.dto; + +import ddangkong.domain.balance.option.BalanceOption; +import ddangkong.domain.balance.vote.BalanceVote; +import java.util.List; + +public record BalanceOptionGroupResponse( + Long optionId, + String name, + List members, + int memberCount, + int percent +) { + public static BalanceOptionGroupResponse of(BalanceOption balanceOption, + List balanceVotes, + int totalSize) { + List members = balanceVotes.stream() + .map(BalanceVote::getMemberNickname) + .toList(); + return new BalanceOptionGroupResponse(balanceOption.getId(), + balanceOption.getName(), + members, + balanceVotes.size(), + (int) Math.round(balanceVotes.size() * 1.0 / totalSize * 100)); + } +} diff --git a/backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionTotalResponse.java b/backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionTotalResponse.java new file mode 100644 index 00000000..e658974c --- /dev/null +++ b/backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionTotalResponse.java @@ -0,0 +1,17 @@ +package ddangkong.controller.balance.option.dto; + +import ddangkong.domain.balance.option.BalanceOption; + +public record BalanceOptionTotalResponse( + Long optionId, + String name, + int percent +) { + public static BalanceOptionTotalResponse of(BalanceOption balanceOption, + Long totalSize, + Long optionSize) { + return new BalanceOptionTotalResponse(balanceOption.getId(), + balanceOption.getName(), + (int) Math.round(optionSize * 1.0 / totalSize * 100)); + } +} diff --git a/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java b/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java index 848cabf3..26759f23 100644 --- a/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java +++ b/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java @@ -1,5 +1,6 @@ package ddangkong.controller.balance.vote; +import ddangkong.controller.balance.vote.dto.BalanceVoteResultResponse; import ddangkong.controller.balance.vote.dto.BalanceVoteRequest; import ddangkong.controller.balance.vote.dto.BalanceVoteResponse; import ddangkong.service.balance.vote.BalanceVoteService; @@ -8,6 +9,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -23,6 +25,12 @@ public class BalanceVoteController { private final BalanceVoteService balanceVoteService; + @GetMapping("/balances/rooms/{roomId}/contents/{contentId}/vote-result") + public BalanceVoteResultResponse getBalanceRoundResult(@PathVariable @Positive Long roomId, + @PathVariable @Positive Long contentId) { + return balanceVoteService.findBalanceVoteResult(roomId, contentId); + } + @PostMapping("/balances/rooms/{roomId}/contents/{contentId}/votes") @ResponseStatus(HttpStatus.CREATED) public BalanceVoteResponse createBalanceVote(@PathVariable @Positive Long roomId, diff --git a/backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteResultResponse.java b/backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteResultResponse.java new file mode 100644 index 00000000..172ed0d1 --- /dev/null +++ b/backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteResultResponse.java @@ -0,0 +1,11 @@ +package ddangkong.controller.balance.vote.dto; + +import ddangkong.controller.balance.content.dto.BalanceContentGroupResponse; +import ddangkong.controller.balance.content.dto.BalanceContentTotalResponse; + +public record BalanceVoteResultResponse( + BalanceContentGroupResponse group, + BalanceContentTotalResponse total +) { + +} diff --git a/backend/src/main/java/ddangkong/domain/balance/content/BalanceContentRepository.java b/backend/src/main/java/ddangkong/domain/balance/content/BalanceContentRepository.java new file mode 100644 index 00000000..5ed28c7d --- /dev/null +++ b/backend/src/main/java/ddangkong/domain/balance/content/BalanceContentRepository.java @@ -0,0 +1,13 @@ +package ddangkong.domain.balance.content; + +import ddangkong.domain.balance.option.BalanceOption; +import ddangkong.exception.BadRequestException; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface BalanceContentRepository extends JpaRepository { + + default BalanceContent getById(Long id) { + return findById(id) + .orElseThrow(() -> new BadRequestException("해당 질문 컨텐츠가 존재하지 않습니다.")); + } +} diff --git a/backend/src/main/java/ddangkong/domain/balance/option/BalanceOptionRepository.java b/backend/src/main/java/ddangkong/domain/balance/option/BalanceOptionRepository.java index d30016c0..29125050 100644 --- a/backend/src/main/java/ddangkong/domain/balance/option/BalanceOptionRepository.java +++ b/backend/src/main/java/ddangkong/domain/balance/option/BalanceOptionRepository.java @@ -7,7 +7,7 @@ public interface BalanceOptionRepository extends JpaRepository { - List findByBalanceContent(BalanceContent balanceContent); + List findAllByBalanceContent(BalanceContent balanceContent); default BalanceOption getById(Long id) { return findById(id) diff --git a/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVote.java b/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVote.java index 717a3634..0feec949 100644 --- a/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVote.java +++ b/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVote.java @@ -38,4 +38,8 @@ public BalanceVote(BalanceOption balanceOption, Member member) { public Long getOptionId() { return balanceOption.getId(); } + + public String getMemberNickname() { + return member.getNickname(); + } } diff --git a/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVoteRepository.java b/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVoteRepository.java index 9e3d851f..570a196a 100644 --- a/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVoteRepository.java +++ b/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVoteRepository.java @@ -1,6 +1,13 @@ package ddangkong.domain.balance.vote; +import ddangkong.domain.balance.option.BalanceOption; +import ddangkong.domain.balance.room.Room; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; public interface BalanceVoteRepository extends JpaRepository { + // List findAllByBalanceOption(BalanceOption balanceOption); + Long countByBalanceOption(BalanceOption balanceOption); + + List findByMemberRoomAndBalanceOption(Room room, BalanceOption balanceOption); } diff --git a/backend/src/main/java/ddangkong/domain/member/MemberRepository.java b/backend/src/main/java/ddangkong/domain/member/MemberRepository.java index 0ff00d9d..f1608703 100644 --- a/backend/src/main/java/ddangkong/domain/member/MemberRepository.java +++ b/backend/src/main/java/ddangkong/domain/member/MemberRepository.java @@ -7,7 +7,7 @@ public interface MemberRepository extends JpaRepository { - List findByRoom(Room room); + List findAllByRoom(Room room); default Member getById(Long id) { return findById(id) diff --git a/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java b/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java index 8c23218c..edfe5992 100644 --- a/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java +++ b/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java @@ -46,7 +46,7 @@ private RoomContent findCurrentRoomContent(Long roomId) { } private List findBalanceOptions(BalanceContent balanceContent) { - List balanceOptions = balanceOptionRepository.findByBalanceContent(balanceContent); + List balanceOptions = balanceOptionRepository.findAllByBalanceContent(balanceContent); validateBalanceOptions(balanceOptions); return balanceOptions; } diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index 4fe29816..8fadbc09 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -39,7 +39,7 @@ public RoomJoinResponse joinRoom(String nickname, Long roomId) { public RoomMembersResponse findAllRoomMember(Long roomId) { Room room = roomRepository.getById(roomId); - List response = memberRepository.findByRoom(room) + List response = memberRepository.findAllByRoom(room) .stream() .map(RoomMemberResponse::new) .toList(); diff --git a/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java b/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java index 30dae02f..9f137c8f 100644 --- a/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java +++ b/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java @@ -1,14 +1,28 @@ package ddangkong.service.balance.vote; +import ddangkong.controller.balance.content.dto.BalanceContentGroupResponse; +import ddangkong.controller.balance.content.dto.BalanceContentTotalResponse; +import ddangkong.controller.balance.option.dto.BalanceOptionGroupResponse; +import ddangkong.controller.balance.option.dto.BalanceOptionTotalResponse; +import ddangkong.controller.balance.vote.dto.BalanceVoteResultResponse; import ddangkong.controller.balance.vote.dto.BalanceVoteRequest; import ddangkong.controller.balance.vote.dto.BalanceVoteResponse; +import ddangkong.domain.balance.content.BalanceContent; +import ddangkong.domain.balance.content.BalanceContentRepository; import ddangkong.domain.balance.option.BalanceOption; import ddangkong.domain.balance.option.BalanceOptionRepository; +import ddangkong.domain.balance.room.Room; +import ddangkong.domain.balance.room.RoomContent; +import ddangkong.domain.balance.room.RoomContentRepository; +import ddangkong.domain.balance.room.RoomRepository; import ddangkong.domain.balance.vote.BalanceVote; import ddangkong.domain.balance.vote.BalanceVoteRepository; import ddangkong.domain.member.Member; import ddangkong.domain.member.MemberRepository; import ddangkong.exception.BadRequestException; +import ddangkong.exception.InternalServerException; +import java.util.List; +import java.util.Objects; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -17,12 +31,20 @@ @RequiredArgsConstructor public class BalanceVoteService { + private static final int BALANCE_OPTION_SIZE = 2; + private final BalanceVoteRepository balanceVoteRepository; private final MemberRepository memberRepository; private final BalanceOptionRepository balanceOptionRepository; + private final BalanceContentRepository balanceContentRepository; + + private final RoomContentRepository roomContentRepository; + + private final RoomRepository roomRepository; + @Transactional public BalanceVoteResponse createBalanceVote(BalanceVoteRequest request, Long roomId, Long contentId) { BalanceOption balanceOption = findValidOption(request.optionId(), contentId); @@ -52,4 +74,70 @@ private Member findValidMember(Long memberId, Long roomId) { } return member; } + + @Transactional(readOnly = true) + public BalanceVoteResultResponse findBalanceVoteResult(Long roomId, Long balanceContentId) { + Room room = roomRepository.getById(roomId); + List balanceOptions = findBalanceOptions(room, balanceContentId); + + BalanceOption firstOption = balanceOptions.get(0); + BalanceOption secondOption = balanceOptions.get(1); + + BalanceContentGroupResponse group = getBalanceContentGroupResponse(room, firstOption, secondOption); + BalanceContentTotalResponse total = getBalanceContentTotalResponse(firstOption, secondOption); + + return new BalanceVoteResultResponse(group, total); + } + + private BalanceContentGroupResponse getBalanceContentGroupResponse(Room room, + BalanceOption firstOption, + BalanceOption secondOption) { + List firstOptionVotes = balanceVoteRepository + .findByMemberRoomAndBalanceOption(room, firstOption); + List secondOptionVotes = balanceVoteRepository + .findByMemberRoomAndBalanceOption(room, secondOption); + + int roomMemberSize = firstOptionVotes.size() + secondOptionVotes.size(); + return new BalanceContentGroupResponse( + BalanceOptionGroupResponse.of(firstOption, firstOptionVotes, roomMemberSize), + BalanceOptionGroupResponse.of(secondOption, secondOptionVotes, roomMemberSize) + ); + } + + private BalanceContentTotalResponse getBalanceContentTotalResponse(BalanceOption firstOption, + BalanceOption secondOption) { + Long firstOptionCount = balanceVoteRepository.countByBalanceOption(firstOption); + Long secondOptionCount = balanceVoteRepository.countByBalanceOption(secondOption); + return new BalanceContentTotalResponse( + BalanceOptionTotalResponse.of(firstOption, + firstOptionCount + secondOptionCount, + firstOptionCount), + BalanceOptionTotalResponse.of(secondOption, + firstOptionCount + secondOptionCount, + secondOptionCount) + ); + } + + private List findBalanceOptions(Room room, Long balanceContentId) { + RoomContent roomContent = roomContentRepository.findByRoomAndRound(room, room.getCurrentRound()) + .orElseThrow(() -> new BadRequestException("해당 방의 현재 진행중인 질문이 존재하지 않습니다.")); + validateBalanceContent(balanceContentId, roomContent.getBalanceContent()); + + BalanceContent balanceContent = balanceContentRepository.getById(balanceContentId); + List balanceOptions = balanceOptionRepository.findAllByBalanceContent(balanceContent); + validateBalanceOptions(balanceOptions); + return balanceOptions; + } + + private void validateBalanceContent(Long balanceContentId, BalanceContent balanceContent) { + if (!Objects.equals(balanceContent.getId(), balanceContentId)) { + throw new BadRequestException("현재 진행중인 질문의 컨텐츠와 일치하지 않는 요청입니다."); + } + } + + private void validateBalanceOptions(List balanceOptions) { + if (balanceOptions.size() != BALANCE_OPTION_SIZE) { + throw new InternalServerException("밸런스 게임의 선택지가 %d개입니다".formatted(balanceOptions.size())); + } + } } diff --git a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java index 638e653d..f938baa1 100644 --- a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java @@ -21,7 +21,7 @@ class BalanceContentServiceTest extends BaseServiceTest { class 현재_방의_밸런스_게임_내용_조회 { private static final Long PROGRESS_ROOM_ID = 1L; - private static final Long NOT_EXIST_ROOM_ID = 3L; + private static final Long NOT_EXIST_ROOM_ID = 99999999L; private static final Long NOT_PROGRESSED_ROOM_ID = 2L; private static final BalanceContentResponse BALANCE_CONTENT_RESPONSE = new BalanceContentResponse( 1L, Category.EXAMPLE, 5, 2, "민초 vs 반민초", diff --git a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java index 17460189..69b569fe 100644 --- a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java @@ -25,8 +25,8 @@ class 방_생성 { void 방_생성_시_멤버를_생성하고_방을_생성한다() { // given String nickname = "나는방장"; - MemberResponse expectedMemberResponse = new MemberResponse(5L, nickname, true); - RoomJoinResponse expected = new RoomJoinResponse(3L, expectedMemberResponse); + MemberResponse expectedMemberResponse = new MemberResponse(7L, nickname, true); + RoomJoinResponse expected = new RoomJoinResponse(4L, expectedMemberResponse); // when RoomJoinResponse actual = roomService.createRoom(nickname); @@ -44,7 +44,7 @@ class 방_참여 { // given String nickname = "나는참가자"; Long joinRoomId = 2L; - MemberResponse expectedMemberResponse = new MemberResponse(5L, nickname, false); + MemberResponse expectedMemberResponse = new MemberResponse(7L, nickname, false); RoomJoinResponse expected = new RoomJoinResponse(joinRoomId, expectedMemberResponse); // when diff --git a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java index 3d40ab78..863a3bfa 100644 --- a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java @@ -3,10 +3,16 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import ddangkong.controller.balance.content.dto.BalanceContentGroupResponse; +import ddangkong.controller.balance.content.dto.BalanceContentTotalResponse; +import ddangkong.controller.balance.option.dto.BalanceOptionGroupResponse; +import ddangkong.controller.balance.option.dto.BalanceOptionTotalResponse; import ddangkong.controller.balance.vote.dto.BalanceVoteRequest; import ddangkong.controller.balance.vote.dto.BalanceVoteResponse; +import ddangkong.controller.balance.vote.dto.BalanceVoteResultResponse; import ddangkong.exception.BadRequestException; import ddangkong.service.BaseServiceTest; +import java.util.List; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -66,4 +72,42 @@ class 투표_생성 { .hasMessage("해당 방의 멤버가 아닙니다. roomId : 2, memberId : 1"); } } + + @Nested + class 투표_결과_조회 { + + @Test + void 투표_결과를_조회한다() { + // given + BalanceVoteResultResponse expected = new BalanceVoteResultResponse( + new BalanceContentGroupResponse( + new BalanceOptionGroupResponse(1L, + "민초", + List.of("mohamedeu al katan", "deundeun", "rupi"), + 3, 75), + new BalanceOptionGroupResponse(2L, + "반민초", + List.of("rapper lee"), 1, 25) + ), + new BalanceContentTotalResponse( + new BalanceOptionTotalResponse(1L, "민초", 50), + new BalanceOptionTotalResponse(2L, "반민초", 50) + ) + ); + + // when + BalanceVoteResultResponse actual = balanceVoteService.findBalanceVoteResult(1L, 1L); + + // then + assertThat(actual).isEqualTo(expected); + } + + @Test + void 진행중인_주제가_아닌것의_투표_결과를_요청하면_예외를_발생시킨다() { + // when & then + assertThatThrownBy(() -> balanceVoteService.findBalanceVoteResult(1L, 2L)) + .isInstanceOf(BadRequestException.class); + } + + } } diff --git a/backend/src/test/resources/init-test.sql b/backend/src/test/resources/init-test.sql index a259fc40..e4683587 100644 --- a/backend/src/test/resources/init-test.sql +++ b/backend/src/test/resources/init-test.sql @@ -1,12 +1,15 @@ INSERT INTO room (total_round, current_round) VALUES (5, 2), + (5, 1), (5, 1); INSERT INTO member (nickname, room_id, is_master) VALUES ('mohamedeu al katan', 1, true), ('deundeun', 1, false), ('rupi', 1, false), - ('rapper lee', 1, false); + ('rapper lee', 1, false), + ('alpha', 2, true), + ('bravo', 2, false); INSERT INTO balance_content (category, name) VALUES ('EXAMPLE', '민초 vs 반민초'), @@ -14,7 +17,8 @@ VALUES ('EXAMPLE', '민초 vs 반민초'), INSERT INTO room_content (room_id, balance_content_id, round, created_at) VALUES (1, 2, 1, '2024-07-18 19:50:00.000'), - (1, 1, 2, '2024-07-18 20:00:00.000'); + (1, 1, 2, '2024-07-18 20:00:00.000'), + (3, 1, 1, '2024-07-18 19:51:00.000'); INSERT INTO balance_option (name, balance_content_id) VALUES ('민초', 1), @@ -27,6 +31,9 @@ VALUES (4, 1), (4, 2), (4, 3), (4, 4), + (1, 1), (1, 2), (1, 3), - (2, 4); + (2, 4), + (2, 5), + (2, 6); From e2cda43d5a3cccf1b0db42a4231b1a39766763df Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 25 Jul 2024 23:56:45 +0900 Subject: [PATCH 0303/1013] =?UTF-8?q?chore:=20SQL=20data-dev.sql=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EC=82=BD=EC=9E=85=20#76?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/main/resources/sql/data-dev.sql | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/backend/src/main/resources/sql/data-dev.sql b/backend/src/main/resources/sql/data-dev.sql index e5e5ef82..31bc5a06 100644 --- a/backend/src/main/resources/sql/data-dev.sql +++ b/backend/src/main/resources/sql/data-dev.sql @@ -5,6 +5,7 @@ VALUES ('EXAMPLE', '민초 vs 반민초'), ('EXAMPLE', '개구리 맛 초콜릿 vs 초콜릿 맛 개구리'), ('EXAMPLE', '언제 죽을 지 알기 vs 어떻게 죽을 지 알기'); + INSERT INTO balance_option (name, balance_content_id) VALUES ('민초', 1), ('반민초', 1), @@ -16,3 +17,19 @@ VALUES ('민초', 1), ('초콜릿 맛 개구리', 4), ('언제 죽을 지 알기', 5), ('어떻게 죽을 지 알기', 5); + + +INSERT INTO room(total_round, current_round) +VALUES (5, 1); + + +INSERT INTO room_content(room_id, balance_content_id, round, created_at) +VALUES (1, 1, 1, '2024-07-25 13:24:09'), + (1, 2, 1, '2024-07-25 13:24:09'), + (1, 3, 1, '2024-07-25 13:24:09'), + (1, 4, 1, '2024-07-25 13:24:09'), + (1, 5, 1, '2024-07-25 13:24:09'); + + +INSERT INTO member(room_id, nickname, is_master) +VALUES (1, '콩콩', true); From 43c9903c262486d83dfe127b31546fcfb2e928ae Mon Sep 17 00:00:00 2001 From: jhon3242 Date: Thu, 25 Jul 2024 23:57:33 +0900 Subject: [PATCH 0304/1013] =?UTF-8?q?style:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=A3=BC=EC=84=9D=20=EB=B0=8F=20=EA=B0=9C=ED=96=89?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20#68?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/balance/vote/dto/BalanceVoteResultResponse.java | 1 - .../ddangkong/domain/balance/vote/BalanceVoteRepository.java | 1 - .../ddangkong/service/balance/vote/BalanceVoteServiceTest.java | 1 - 3 files changed, 3 deletions(-) diff --git a/backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteResultResponse.java b/backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteResultResponse.java index 172ed0d1..e985c004 100644 --- a/backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteResultResponse.java +++ b/backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteResultResponse.java @@ -7,5 +7,4 @@ public record BalanceVoteResultResponse( BalanceContentGroupResponse group, BalanceContentTotalResponse total ) { - } diff --git a/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVoteRepository.java b/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVoteRepository.java index 570a196a..6a087421 100644 --- a/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVoteRepository.java +++ b/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVoteRepository.java @@ -6,7 +6,6 @@ import org.springframework.data.jpa.repository.JpaRepository; public interface BalanceVoteRepository extends JpaRepository { - // List findAllByBalanceOption(BalanceOption balanceOption); Long countByBalanceOption(BalanceOption balanceOption); List findByMemberRoomAndBalanceOption(Room room, BalanceOption balanceOption); diff --git a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java index 863a3bfa..2b92f7a2 100644 --- a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java @@ -108,6 +108,5 @@ class 투표_결과_조회 { assertThatThrownBy(() -> balanceVoteService.findBalanceVoteResult(1L, 2L)) .isInstanceOf(BadRequestException.class); } - } } From 2b6b85dcd705bbe9f99ffe617d74eab4d7c5e8c2 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Fri, 26 Jul 2024 00:24:48 +0900 Subject: [PATCH 0305/1013] =?UTF-8?q?fix:=20SPRING=5FPROFILE=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20args=20->=20environment=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20#76?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/Dockerfile | 3 --- backend/deploy/docker-compose-dev.yml | 8 ++++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 2e224430..3e70f8ba 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,9 +1,6 @@ FROM openjdk:17-jdk-slim ARG JAR_FILE=build/libs/*.jar -ARG SPRING_PROFILE - -ENV SPRING_PROFILE=${SPRING_PROFILE} COPY ${JAR_FILE} app.jar diff --git a/backend/deploy/docker-compose-dev.yml b/backend/deploy/docker-compose-dev.yml index 3c84c791..074136ff 100644 --- a/backend/deploy/docker-compose-dev.yml +++ b/backend/deploy/docker-compose-dev.yml @@ -1,4 +1,4 @@ -version: "2.29.0" +version: "3.8" services: ddangkong-api-dev: @@ -6,7 +6,7 @@ services: build: context: ../ dockerfile: Dockerfile - args: - - SPRINT_PROFILE=dev + environment: + - SPRING_PROFILE=dev ports: - - "8080:8080" + - "80:8080" From e9d0a34da7858200f1fcf4f2e21288af299b271c Mon Sep 17 00:00:00 2001 From: useon Date: Fri, 26 Jul 2024 04:38:01 +0900 Subject: [PATCH 0306/1013] =?UTF-8?q?refactor:=20=EB=8B=89=EB=84=A4?= =?UTF-8?q?=EC=9E=84=20=EC=95=84=EC=9D=B4=ED=85=9C=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=8B=9C=EB=A7=A8=ED=8B=B1=20=ED=83=9C?= =?UTF-8?q?=EA=B7=B8=EB=A1=9C=20=EC=88=98=EC=A0=95=20#72?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NicknameItem/NicknameItem.styled.ts | 15 +++++++-------- .../src/components/NicknameItem/NicknameItem.tsx | 16 ++++++++++------ 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/frontend/src/components/NicknameItem/NicknameItem.styled.ts b/frontend/src/components/NicknameItem/NicknameItem.styled.ts index 8fc9e588..5ef4f8b5 100644 --- a/frontend/src/components/NicknameItem/NicknameItem.styled.ts +++ b/frontend/src/components/NicknameItem/NicknameItem.styled.ts @@ -1,12 +1,11 @@ import { css } from '@emotion/react'; -import { Theme } from '@/styles/Theme'; - -export const profileImage = css` - width: 4rem; - height: 4rem; - margin-top: 4rem; - border-radius: 50%; +export const nicknameListLayout = css` + display: flex; + gap: 1.2rem; + width: 50%; +`; - background-color: ${Theme.color.gray300}; +export const nicknameText = css` + font-size: 1.2rem; `; diff --git a/frontend/src/components/NicknameItem/NicknameItem.tsx b/frontend/src/components/NicknameItem/NicknameItem.tsx index 94f3787d..aa1f8fc4 100644 --- a/frontend/src/components/NicknameItem/NicknameItem.tsx +++ b/frontend/src/components/NicknameItem/NicknameItem.tsx @@ -1,11 +1,15 @@ -import { profileImage } from './NicknameItem.styled'; +import { nicknameListLayout, nicknameText } from './NicknameItem.styled'; -const NicknameItem = (member: string) => { +interface NicknameItemProp { + member: string; +} + +const NicknameItem = ({ member }: NicknameItemProp) => { return ( -
-
- {member} -
+
  • + 🥜 + {member} +
  • ); }; From efd823eb2603b4525ed81b8cae8491560a49cce9 Mon Sep 17 00:00:00 2001 From: useon Date: Fri, 26 Jul 2024 04:41:42 +0900 Subject: [PATCH 0307/1013] =?UTF-8?q?refactor:=20=EB=8B=89=EB=84=A4?= =?UTF-8?q?=EC=9E=84=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=95=84=EC=9B=83=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EB=94=94?= =?UTF-8?q?=EC=9E=90=EC=9D=B8=20=ED=86=A0=ED=81=B0=20=EC=A0=81=EC=9A=A9=20?= =?UTF-8?q?#72?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/NicknameList/NicknameList.styled.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/NicknameList/NicknameList.styled.ts b/frontend/src/components/NicknameList/NicknameList.styled.ts index 28f20d46..1e5d34cd 100644 --- a/frontend/src/components/NicknameList/NicknameList.styled.ts +++ b/frontend/src/components/NicknameList/NicknameList.styled.ts @@ -1,10 +1,12 @@ import { css } from '@emotion/react'; +import { Theme } from '@/styles/Theme'; + export const nicknameListLayout = css` display: flex; justify-content: space-around; - width: 24.4rem; - height: 15.8rem; + width: 100%; + row-gap: 1.2rem; `; export const nicknameContainer = css` @@ -17,5 +19,5 @@ export const verticalLine = css` width: 0.1rem; height: 100%; - background-color: #d9d9d9; + background-color: ${Theme.color.gray}; `; From ace02bbce170a4072a64079a30d4ab91fa300633 Mon Sep 17 00:00:00 2001 From: useon Date: Fri, 26 Jul 2024 04:51:28 +0900 Subject: [PATCH 0308/1013] =?UTF-8?q?feat:=20=EC=84=A0=ED=83=9D=EC=A7=80,?= =?UTF-8?q?=20=EC=84=A0=ED=83=9D=ED=95=9C=20=EC=82=AC=EB=9E=8C=20=EC=88=98?= =?UTF-8?q?,=20=EC=84=A0=ED=83=9D=ED=95=9C=20=EC=82=AC=EB=9E=8C=20?= =?UTF-8?q?=EB=8B=89=EB=84=A4=EC=9E=84=EC=9D=84=20=EB=B3=B4=EC=97=AC?= =?UTF-8?q?=EC=A3=BC=EB=8A=94=20OptionParticipants=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84=20#72?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OptionParticipants.styled.ts | 20 +++++++++++++ .../OptionParticipants/OptionParticipants.tsx | 29 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 frontend/src/components/OptionParticipants/OptionParticipants.styled.ts create mode 100644 frontend/src/components/OptionParticipants/OptionParticipants.tsx diff --git a/frontend/src/components/OptionParticipants/OptionParticipants.styled.ts b/frontend/src/components/OptionParticipants/OptionParticipants.styled.ts new file mode 100644 index 00000000..fc06274a --- /dev/null +++ b/frontend/src/components/OptionParticipants/OptionParticipants.styled.ts @@ -0,0 +1,20 @@ +import { css } from '@emotion/react'; + +export const optionParticipantsLayout = css` + display: flex; + flex-direction: column; + gap: 2rem; + width: 100%; +`; + +export const optionInfo = css` + font-weight: bold; + font-size: 1.6rem; +`; + +export const participantsListWrapper = css` + display: flex; + flex-wrap: wrap; + row-gap: 1.2rem; + list-style: none; +`; diff --git a/frontend/src/components/OptionParticipants/OptionParticipants.tsx b/frontend/src/components/OptionParticipants/OptionParticipants.tsx new file mode 100644 index 00000000..9bff8a05 --- /dev/null +++ b/frontend/src/components/OptionParticipants/OptionParticipants.tsx @@ -0,0 +1,29 @@ +import { + optionInfo, + optionParticipantsLayout, + participantsListWrapper, +} from './OptionParticipants.styled'; +import NicknameItem from '../NicknameItem/NicknameItem'; + +export interface OptionParticipantsProps { + optionName: string; + memberCount: number; + members: string[]; +} + +const OptionParticipants = ({ optionName, memberCount, members }: OptionParticipantsProps) => { + return ( +
    +

    + {optionName}: {memberCount} +

    +
      + {members.map((member, index) => ( + + ))} +
    +
    + ); +}; + +export default OptionParticipants; From 2ffce4815ad3a4e174cef98dde659ba98f6fe6c1 Mon Sep 17 00:00:00 2001 From: useon Date: Fri, 26 Jul 2024 04:53:19 +0900 Subject: [PATCH 0309/1013] =?UTF-8?q?feat:=20=EC=84=A0=ED=83=9D=EC=A7=80?= =?UTF-8?q?=20=EB=B3=84=20=EC=9D=91=EB=8B=B5=EC=9D=84=20=EB=AA=A8=EB=91=90?= =?UTF-8?q?=20=EB=B3=BC=20=EC=88=98=20=EC=9E=88=EB=8A=94=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84=20#72?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OptionParticipantsContainer.styled.ts | 17 ++++++++ .../OptionParticipantsContainer.tsx | 39 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.styled.ts create mode 100644 frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx diff --git a/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.styled.ts b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.styled.ts new file mode 100644 index 00000000..9b32aae2 --- /dev/null +++ b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.styled.ts @@ -0,0 +1,17 @@ +import { css } from '@emotion/react'; + +import { Theme } from '@/styles/Theme'; + +export const optionParticipantsContainerLayout = css` + display: flex; + flex-direction: column; + row-gap: 2rem; +`; + +export const dividerLine = css` + width: 100%; + height: 1px; + margin: 1.5rem 0; + + background-color: ${Theme.color.gray300}; +`; diff --git a/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx new file mode 100644 index 00000000..c686e3d1 --- /dev/null +++ b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx @@ -0,0 +1,39 @@ +import { + dividerLine, + optionParticipantsContainerLayout, +} from './OptionParticipantsContainer.styled'; +import OptionParticipants from '../OptionParticipants/OptionParticipants'; +import TopicContainer from '../TopicContainer/TopicContainer'; + +import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; +import useRoundVoteResultQuery from '@/hooks/useRoundVoteResultQuery'; + +const OptionParticipantsContainer = () => { + const { balanceContent } = useBalanceContentQuery(); + const { groupRoundResult } = useRoundVoteResultQuery(); + + if (!balanceContent || !groupRoundResult) { + return null; + } + + return ( + <> + +
    + +
    + +
    + + ); +}; + +export default OptionParticipantsContainer; From ed751d5e36ac5a055b55672f1088faeb4a382841 Mon Sep 17 00:00:00 2001 From: useon Date: Fri, 26 Jul 2024 04:54:38 +0900 Subject: [PATCH 0310/1013] =?UTF-8?q?feat:=20=ED=88=AC=ED=91=9C=20?= =?UTF-8?q?=ED=98=84=ED=99=A9=20=ED=8E=98=EC=9D=B4=EC=A7=80=20router=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#72?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/TabContentContainer/TabContentContainer.tsx | 6 +++--- frontend/src/router/index.tsx | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/TabContentContainer/TabContentContainer.tsx b/frontend/src/components/TabContentContainer/TabContentContainer.tsx index 4ccbdc2f..4184b1f3 100644 --- a/frontend/src/components/TabContentContainer/TabContentContainer.tsx +++ b/frontend/src/components/TabContentContainer/TabContentContainer.tsx @@ -32,8 +32,8 @@ const TabContentContainer = ({ const isBigFirstOption = roundResult.firstOption.percent >= 50; - const goToCurrentVote = () => { - navigate('/round/result/current'); + const goToVoteStatus = () => { + navigate('/round/result/status'); }; return (
    @@ -61,7 +61,7 @@ const TabContentContainer = ({
    -
    diff --git a/frontend/src/router/index.tsx b/frontend/src/router/index.tsx index 02cb7b7d..c5dc30f9 100644 --- a/frontend/src/router/index.tsx +++ b/frontend/src/router/index.tsx @@ -7,12 +7,17 @@ import GameResultPage from '@/pages/GameResultPage/GameResultPage'; import MainPage from '@/pages/MainPage/MainPage'; import NicknamePage from '@/pages/NicknamePage/NicknamePage'; import RoundResultPage from '@/pages/RoundResultPage/RoundResultPage'; +import VoteStatusPage from '@/pages/VoteStatusPage/VoteStatusPage'; export const router = createBrowserRouter([ { path: '/', element: , }, + { + path: 'round/result/status', + element: , + }, { path: '/', element: , From b352bd86bd99086ac5de7954c65e0faf8f417921 Mon Sep 17 00:00:00 2001 From: useon Date: Fri, 26 Jul 2024 04:56:05 +0900 Subject: [PATCH 0311/1013] =?UTF-8?q?feat:=20=EC=84=A0=ED=83=9D=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EC=83=9D=EC=84=B1=20#72?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/SelectButton/SelectButton.tsx | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 frontend/src/components/common/SelectButton/SelectButton.tsx diff --git a/frontend/src/components/common/SelectButton/SelectButton.tsx b/frontend/src/components/common/SelectButton/SelectButton.tsx new file mode 100644 index 00000000..e866d840 --- /dev/null +++ b/frontend/src/components/common/SelectButton/SelectButton.tsx @@ -0,0 +1,29 @@ +import { useNavigate } from 'react-router-dom'; + +import Button from '../Button/Button'; +import { bottomButtonLayout } from '../Button/Button.styled'; + +interface SelectButtonProps { + isDisabled: boolean; +} + +const SelectButton = ({ isDisabled }: SelectButtonProps) => { + const navigate = useNavigate(); + + const goToRoundResult = () => { + navigate(`/round/result`); + }; + + return ( +
    +
    + ); +}; + +export default SelectButton; From 5d08fc442faacdc92f19ffadf83f9adf79e47c21 Mon Sep 17 00:00:00 2001 From: useon Date: Fri, 26 Jul 2024 04:56:43 +0900 Subject: [PATCH 0312/1013] =?UTF-8?q?refactor:=20=EC=84=A0=ED=83=9D=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EC=A0=81=EC=9A=A9=20#72?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/SelectContainer/SelectContainer.tsx | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/frontend/src/components/SelectContainer/SelectContainer.tsx b/frontend/src/components/SelectContainer/SelectContainer.tsx index a873db46..642e4b12 100644 --- a/frontend/src/components/SelectContainer/SelectContainer.tsx +++ b/frontend/src/components/SelectContainer/SelectContainer.tsx @@ -1,21 +1,15 @@ import { useState } from 'react'; -import { useNavigate } from 'react-router-dom'; import { selectContainerLayout, selectSection } from './SelectContainer.styled'; +import SelectButton from '../common/SelectButton/SelectButton'; -import Button from '@/components/common/Button/Button'; import SelectOption from '@/components/SelectOption/SelectOption'; import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; const SelectContainer = () => { - const navigate = useNavigate(); const { balanceContent, isLoading } = useBalanceContentQuery(); const [selectedId, setSelectedId] = useState(0); - const goToRoundResult = () => { - navigate(`/round/result`); - }; - const handleSelectOption = (selectedId: number) => { setSelectedId(selectedId); }; @@ -39,8 +33,7 @@ const SelectContainer = () => { handleSelectOption={handleSelectOption} /> - - + ); +}; + +interface ModalTextButtonProps extends ButtonHTMLAttributes { + buttonWidth?: string; + buttonHeight?: string; + fontSize?: string; + backgroundColor?: string; + fontColor?: string; +} + +const ModalTextButton = ({ + type = 'button', + buttonWidth, + buttonHeight, + fontSize, + backgroundColor, + fontColor, + ...restProps +}: ModalTextButtonProps) => { + return ( + ); }; diff --git a/frontend/src/pages/ReadyPage/ReadyPage.styled.ts b/frontend/src/pages/ReadyPage/ReadyPage.styled.ts index b54975a9..84b7ae3a 100644 --- a/frontend/src/pages/ReadyPage/ReadyPage.styled.ts +++ b/frontend/src/pages/ReadyPage/ReadyPage.styled.ts @@ -1,15 +1,15 @@ import { css } from '@emotion/react'; export const readyPageLayout = css` - padding: 0 2.4rem; - display: flex; flex-direction: column; gap: 2rem; + padding: 0 2.4rem; `; export const totalNumber = css` padding-left: 2rem; - font-size: 1.2rem; + font-weight: 500; + font-size: 1.2rem; `; diff --git a/frontend/src/router/index.tsx b/frontend/src/router/index.tsx index c5dc30f9..537a8707 100644 --- a/frontend/src/router/index.tsx +++ b/frontend/src/router/index.tsx @@ -6,6 +6,7 @@ import GamePage from '@/pages/GamePage/GamePage'; import GameResultPage from '@/pages/GameResultPage/GameResultPage'; import MainPage from '@/pages/MainPage/MainPage'; import NicknamePage from '@/pages/NicknamePage/NicknamePage'; +import ReadyPage from '@/pages/ReadyPage/ReadyPage'; import RoundResultPage from '@/pages/RoundResultPage/RoundResultPage'; import VoteStatusPage from '@/pages/VoteStatusPage/VoteStatusPage'; @@ -28,7 +29,7 @@ export const router = createBrowserRouter([ }, { path: 'ready', - element:
    게임 대기 화면
    , + element: , }, { path: 'game', From 1ca5264c047abc6bc6955e75baaa9969d805f84f Mon Sep 17 00:00:00 2001 From: leegwichan Date: Wed, 31 Jul 2024 01:18:15 +0900 Subject: [PATCH 0355/1013] =?UTF-8?q?test:=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=20=EC=88=98=EC=A0=95=20#89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기능 명세에 따라 잘못된 테스트 메서드 이름 수정 --- .../balance/vote/BalanceVoteDocumentationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/test/java/ddangkong/documentation/balance/vote/BalanceVoteDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/vote/BalanceVoteDocumentationTest.java index 85ddb12c..ccc3d2e1 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/vote/BalanceVoteDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/vote/BalanceVoteDocumentationTest.java @@ -108,7 +108,7 @@ class 투표_생성 { private static final String END_POINT = "/api/balances/rooms/{roomId}/contents/{contentId}/votes"; @Test - void 방의_진행중인_라운드_결과를_조회한다() throws Exception { + void 선택지에_투표를_할_수_있다() throws Exception { // given Long optionId = 1L; Long contentId = 1L; From cffb23a80ca20dfdd1b1ee9e2807ab6c39cedb88 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Wed, 31 Jul 2024 15:06:42 +0900 Subject: [PATCH 0356/1013] =?UTF-8?q?feat:=20Room=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=20RoomStatus=20=ED=95=84=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20#94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ddangkong/domain/balance/room/Room.java | 23 +++++++++++++++++-- .../domain/balance/room/RoomStatus.java | 7 ++++++ .../service/balance/room/RoomService.java | 2 +- .../domain/balance/room/RoomTest.java | 17 ++++---------- backend/src/test/resources/init-test.sql | 8 +++---- 5 files changed, 38 insertions(+), 19 deletions(-) create mode 100644 backend/src/main/java/ddangkong/domain/balance/room/RoomStatus.java diff --git a/backend/src/main/java/ddangkong/domain/balance/room/Room.java b/backend/src/main/java/ddangkong/domain/balance/room/Room.java index 84c99cc9..dde694bd 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/Room.java @@ -3,13 +3,18 @@ import ddangkong.exception.BadRequestException; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import lombok.AccessLevel; import lombok.Getter; +import lombok.NoArgsConstructor; @Entity @Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class Room { private static final int DEFAULT_TOTAL_ROUND = 5; @@ -20,10 +25,24 @@ public class Room { private Long id; @Column(nullable = false) - private int totalRound = DEFAULT_TOTAL_ROUND; + private int totalRound; @Column(nullable = false) - private int currentRound = START_ROUND; + private int currentRound; + + @Column(nullable = false) + @Enumerated(EnumType.STRING) + private RoomStatus status; + + public static Room createNewRoom() { + return new Room(DEFAULT_TOTAL_ROUND, START_ROUND, RoomStatus.READY); + } + + public Room(int totalRound, int currentRound, RoomStatus status) { + this.totalRound = totalRound; + this.currentRound = currentRound; + this.status = status; + } public void moveToNextRound() { if (canMoveToNextRound()) { diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomStatus.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomStatus.java new file mode 100644 index 00000000..4cab4261 --- /dev/null +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomStatus.java @@ -0,0 +1,7 @@ +package ddangkong.domain.balance.room; + +public enum RoomStatus { + READY, + PROGRESS, + FINISH +} diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index 30e76e9a..27c47792 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -40,7 +40,7 @@ public MembersResponse findAllRoomMember(Long roomId) { @Transactional public RoomJoinResponse createRoom(String nickname) { - Room room = roomRepository.save(new Room()); + Room room = roomRepository.save(Room.createNewRoom()); Member member = memberRepository.save(Member.createMaster(nickname, room)); return new RoomJoinResponse(room.getId(), new MemberResponse(member)); } diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java index cb577350..fd663c58 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java @@ -12,13 +12,11 @@ class RoomTest { @Nested class 다음_라운드로_이동 { - private static final int START_ROUND = 1; - private static final int TOTAL_ROUND = 5; @Test void 다음_라운드로_이동할_수_있다() { // given - Room room = new Room(); + Room room = Room.createNewRoom(); int currentRound = room.getCurrentRound(); int expectedRound = currentRound + 1; @@ -32,19 +30,14 @@ class 다음_라운드로_이동 { @Test void 마지막_라운드_일_경우_예외를_던진다() { // given - Room room = new Room(); - goToFinalRound(room); + final int TOTAL_ROUND = 5; + final int CURRENT_ROUND = 5; + Room room = new Room(TOTAL_ROUND, CURRENT_ROUND, RoomStatus.PROGRESS); // when & then - assertThatThrownBy(() -> room.moveToNextRound()) + assertThatThrownBy(room::moveToNextRound) .isInstanceOf(BadRequestException.class) .hasMessage("마지막 라운드입니다."); } - - private void goToFinalRound(Room room) { - for (int round = START_ROUND; round < TOTAL_ROUND; round++) { - room.moveToNextRound(); - } - } } } diff --git a/backend/src/test/resources/init-test.sql b/backend/src/test/resources/init-test.sql index b570596a..e4da0c35 100644 --- a/backend/src/test/resources/init-test.sql +++ b/backend/src/test/resources/init-test.sql @@ -1,7 +1,7 @@ -INSERT INTO room (total_round, current_round) -VALUES (5, 2), - (5, 1), - (5, 1); +INSERT INTO room (total_round, current_round, status) +VALUES (5, 2, 'PROGRESS'), + (5, 1, 'PROGRESS'), + (5, 1, 'PROGRESS'); INSERT INTO member (nickname, room_id, is_master) VALUES ('mohamedeu al katan', 1, true), From b87219daafc4ad10ccdbad551f077a5ad74bc494 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Wed, 31 Jul 2024 15:48:20 +0900 Subject: [PATCH 0357/1013] =?UTF-8?q?feat:=20=EB=8C=80=EA=B8=B0=EB=B0=A9?= =?UTF-8?q?=20=EB=A9=A4=EB=B2=84=20=EC=A1=B0=ED=9A=8C=20DTO=EC=97=90=20?= =?UTF-8?q?=EB=B0=A9=EC=9D=98=20=EA=B2=8C=EC=9E=84=20=EC=8B=9C=EC=9E=91=20?= =?UTF-8?q?=EC=97=AC=EB=B6=80=20=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=A5=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../balance/member/dto/MembersResponse.java | 15 --------------- .../balance/room/RoomController.java | 8 ++++---- .../balance/room/dto/RoomInfoResponse.java | 19 +++++++++++++++++++ .../domain/balance/room/RoomStatus.java | 17 ++++++++++++++--- .../service/balance/room/RoomService.java | 8 ++++---- .../balance/room/RoomControllerTest.java | 6 +++--- .../service/balance/room/RoomServiceTest.java | 19 ++++++++++--------- 7 files changed, 54 insertions(+), 38 deletions(-) delete mode 100644 backend/src/main/java/ddangkong/controller/balance/member/dto/MembersResponse.java create mode 100644 backend/src/main/java/ddangkong/controller/balance/room/dto/RoomInfoResponse.java diff --git a/backend/src/main/java/ddangkong/controller/balance/member/dto/MembersResponse.java b/backend/src/main/java/ddangkong/controller/balance/member/dto/MembersResponse.java deleted file mode 100644 index 30deadb7..00000000 --- a/backend/src/main/java/ddangkong/controller/balance/member/dto/MembersResponse.java +++ /dev/null @@ -1,15 +0,0 @@ -package ddangkong.controller.balance.member.dto; - -import ddangkong.domain.member.Member; -import java.util.List; - -public record MembersResponse( - List members -) { - public static MembersResponse from(List members) { - List response = members.stream() - .map(MemberResponse::new) - .toList(); - return new MembersResponse(response); - } -} diff --git a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java index 66be313a..8b24da75 100644 --- a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java +++ b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java @@ -1,7 +1,7 @@ package ddangkong.controller.balance.room; import ddangkong.controller.balance.content.dto.BalanceContentResponse; -import ddangkong.controller.balance.member.dto.MembersResponse; +import ddangkong.controller.balance.room.dto.RoomInfoResponse; import ddangkong.controller.balance.room.dto.RoomJoinRequest; import ddangkong.controller.balance.room.dto.RoomJoinResponse; import ddangkong.service.balance.room.RoomService; @@ -26,9 +26,9 @@ public class RoomController { private final RoomService roomService; - @GetMapping("/balances/rooms/{roomId}/members") - public MembersResponse getAllBalanceGameRoomMember(@Positive @PathVariable Long roomId) { - return roomService.findAllRoomMember(roomId); + @GetMapping("/balances/rooms/{roomId}") + public RoomInfoResponse getBalanceGameRoomInfo(@Positive @PathVariable Long roomId) { + return roomService.findRoomInfo(roomId); } @ResponseStatus(HttpStatus.CREATED) diff --git a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomInfoResponse.java b/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomInfoResponse.java new file mode 100644 index 00000000..a4e3c20c --- /dev/null +++ b/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomInfoResponse.java @@ -0,0 +1,19 @@ +package ddangkong.controller.balance.room.dto; + +import ddangkong.controller.balance.member.dto.MemberResponse; +import ddangkong.domain.balance.room.RoomStatus; +import ddangkong.domain.member.Member; +import java.util.List; + +public record RoomInfoResponse( + boolean isGameStart, + List members +) { + public static RoomInfoResponse of(List members, RoomStatus roomStatus) { + List response = members.stream() + .map(MemberResponse::new) + .toList(); + + return new RoomInfoResponse(roomStatus.isGameProgress(), response); + } +} diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomStatus.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomStatus.java index 4cab4261..751cfc18 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomStatus.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomStatus.java @@ -1,7 +1,18 @@ package ddangkong.domain.balance.room; public enum RoomStatus { - READY, - PROGRESS, - FINISH + READY(false), + PROGRESS(true), + FINISH(false), + ; + + private final boolean isGameProgress; + + RoomStatus(boolean isGameProgress) { + this.isGameProgress = isGameProgress; + } + + public boolean isGameProgress() { + return isGameProgress; + } } diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index 27c47792..774cb19c 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -2,7 +2,7 @@ import ddangkong.controller.balance.content.dto.BalanceContentResponse; import ddangkong.controller.balance.member.dto.MemberResponse; -import ddangkong.controller.balance.member.dto.MembersResponse; +import ddangkong.controller.balance.room.dto.RoomInfoResponse; import ddangkong.controller.balance.room.dto.RoomJoinResponse; import ddangkong.domain.balance.option.BalanceOptionRepository; import ddangkong.domain.balance.option.BalanceOptions; @@ -31,11 +31,11 @@ public class RoomService { private final BalanceOptionRepository balanceOptionRepository; @Transactional(readOnly = true) - public MembersResponse findAllRoomMember(Long roomId) { + public RoomInfoResponse findRoomInfo(Long roomId) { Room room = roomRepository.getById(roomId); - List members = memberRepository.findAllByRoom(room); - return MembersResponse.from(members); + + return RoomInfoResponse.of(members, room.getStatus()); } @Transactional diff --git a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java index c4a4c834..ac078d3e 100644 --- a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java @@ -4,8 +4,8 @@ import ddangkong.controller.BaseControllerTest; import ddangkong.controller.balance.content.dto.BalanceContentResponse; -import ddangkong.controller.balance.member.dto.MembersResponse; import ddangkong.controller.balance.option.dto.BalanceOptionResponse; +import ddangkong.controller.balance.room.dto.RoomInfoResponse; import ddangkong.controller.balance.room.dto.RoomJoinResponse; import ddangkong.domain.balance.content.Category; import io.restassured.RestAssured; @@ -24,11 +24,11 @@ class 밸런스_게임_방_전체_멤버_조회 { @Test void 게임_방_전체_멤버_조회() { //when - MembersResponse actual = RestAssured.given() + RoomInfoResponse actual = RestAssured.given() .when().get("/api/balances/rooms/1/members") .then().contentType(ContentType.JSON).log().all() .statusCode(200) - .extract().as(MembersResponse.class); + .extract().as(RoomInfoResponse.class); //then Assertions.assertThat(actual.members()).hasSize(4); diff --git a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java index b4caa61e..c9e65031 100644 --- a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java @@ -5,8 +5,8 @@ import ddangkong.controller.balance.content.dto.BalanceContentResponse; import ddangkong.controller.balance.member.dto.MemberResponse; -import ddangkong.controller.balance.member.dto.MembersResponse; import ddangkong.controller.balance.option.dto.BalanceOptionResponse; +import ddangkong.controller.balance.room.dto.RoomInfoResponse; import ddangkong.controller.balance.room.dto.RoomJoinResponse; import ddangkong.domain.balance.content.Category; import ddangkong.exception.BadRequestException; @@ -22,18 +22,19 @@ class RoomServiceTest extends BaseServiceTest { private RoomService roomService; @Nested - class 게임_방_전체_멤버_조회 { + class 게임_방_정보_조회 { @Test - void 게임_방_전쳬_멤버_조회() { - // given - Long roomId = 1L; - + void 대기중인_게임_방_정보_조회() { // when - MembersResponse actual = roomService.findAllRoomMember(roomId); + RoomJoinResponse room = roomService.createRoom("방장"); + roomService.joinRoom("멤버1", room.roomId()); + roomService.joinRoom("멤버2", room.roomId()); // then - Assertions.assertThat(actual.members()).hasSize(4); + RoomInfoResponse actual = roomService.findRoomInfo(room.roomId()); + Assertions.assertThat(actual.members()).hasSize(3); + Assertions.assertThat(actual.isGameStart()).isFalse(); } } @@ -41,7 +42,7 @@ class 게임_방_전체_멤버_조회 { class 방_생성 { @Test - void 방_생성_시_멤버를_생성하고_방을_생성한다() { + void 방_생성_시_방장_멤버를_생성하고_방을_생성한다() { // given String nickname = "나는방장"; MemberResponse expectedMemberResponse = new MemberResponse(7L, nickname, true); From 4c93898872711fd94bea0e4489aa36a0f886238d Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Wed, 31 Jul 2024 16:09:28 +0900 Subject: [PATCH 0358/1013] =?UTF-8?q?feat:=20Room=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=EC=97=90=20timeLimit=20Field=20=EC=B6=94=EA=B0=80=20#?= =?UTF-8?q?94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../balance/room/dto/RoomInfoResponse.java | 8 +++++--- .../controller/balance/room/dto/RoomSetting.java | 6 ++++++ .../java/ddangkong/domain/balance/room/Room.java | 13 +++++++++++-- .../ddangkong/service/balance/room/RoomService.java | 2 +- .../controller/balance/room/RoomControllerTest.java | 2 +- .../ddangkong/domain/balance/room/RoomTest.java | 3 ++- backend/src/test/resources/init-test.sql | 8 ++++---- 7 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSetting.java diff --git a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomInfoResponse.java b/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomInfoResponse.java index a4e3c20c..f2f3b220 100644 --- a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomInfoResponse.java +++ b/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomInfoResponse.java @@ -1,19 +1,21 @@ package ddangkong.controller.balance.room.dto; import ddangkong.controller.balance.member.dto.MemberResponse; -import ddangkong.domain.balance.room.RoomStatus; +import ddangkong.domain.balance.room.Room; import ddangkong.domain.member.Member; import java.util.List; public record RoomInfoResponse( boolean isGameStart, + RoomSetting roomSetting, List members ) { - public static RoomInfoResponse of(List members, RoomStatus roomStatus) { + public static RoomInfoResponse of(List members, Room room) { List response = members.stream() .map(MemberResponse::new) .toList(); + RoomSetting roomSetting = new RoomSetting(room.getTimeLimit()); - return new RoomInfoResponse(roomStatus.isGameProgress(), response); + return new RoomInfoResponse(room.isGameProgress(), roomSetting, response); } } diff --git a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSetting.java b/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSetting.java new file mode 100644 index 00000000..9837b18f --- /dev/null +++ b/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSetting.java @@ -0,0 +1,6 @@ +package ddangkong.controller.balance.room.dto; + +public record RoomSetting( + int timeLimit +) { +} diff --git a/backend/src/main/java/ddangkong/domain/balance/room/Room.java b/backend/src/main/java/ddangkong/domain/balance/room/Room.java index dde694bd..889da399 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/Room.java @@ -18,6 +18,7 @@ public class Room { private static final int DEFAULT_TOTAL_ROUND = 5; + private static final int DEFAULT_TIME_LIMIT = 10000; private static final int START_ROUND = 1; @Id @@ -30,17 +31,21 @@ public class Room { @Column(nullable = false) private int currentRound; + @Column(nullable = false) + private int timeLimit; + @Column(nullable = false) @Enumerated(EnumType.STRING) private RoomStatus status; public static Room createNewRoom() { - return new Room(DEFAULT_TOTAL_ROUND, START_ROUND, RoomStatus.READY); + return new Room(DEFAULT_TOTAL_ROUND, START_ROUND, DEFAULT_TIME_LIMIT, RoomStatus.READY); } - public Room(int totalRound, int currentRound, RoomStatus status) { + public Room(int totalRound, int currentRound, int timeLimit, RoomStatus status) { this.totalRound = totalRound; this.currentRound = currentRound; + this.timeLimit = timeLimit; this.status = status; } @@ -55,4 +60,8 @@ public void moveToNextRound() { private boolean canMoveToNextRound() { return currentRound < totalRound; } + + public boolean isGameProgress() { + return status.isGameProgress(); + } } diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index 774cb19c..58b4a970 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -35,7 +35,7 @@ public RoomInfoResponse findRoomInfo(Long roomId) { Room room = roomRepository.getById(roomId); List members = memberRepository.findAllByRoom(room); - return RoomInfoResponse.of(members, room.getStatus()); + return RoomInfoResponse.of(members, room); } @Transactional diff --git a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java index ac078d3e..08afa3b7 100644 --- a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java @@ -25,7 +25,7 @@ class 밸런스_게임_방_전체_멤버_조회 { void 게임_방_전체_멤버_조회() { //when RoomInfoResponse actual = RestAssured.given() - .when().get("/api/balances/rooms/1/members") + .when().get("/api/balances/rooms/1") .then().contentType(ContentType.JSON).log().all() .statusCode(200) .extract().as(RoomInfoResponse.class); diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java index fd663c58..8a2ec7e5 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java @@ -32,7 +32,8 @@ class 다음_라운드로_이동 { // given final int TOTAL_ROUND = 5; final int CURRENT_ROUND = 5; - Room room = new Room(TOTAL_ROUND, CURRENT_ROUND, RoomStatus.PROGRESS); + final int TIME_LIMIT = 10000; + Room room = new Room(TOTAL_ROUND, CURRENT_ROUND, TIME_LIMIT, RoomStatus.PROGRESS); // when & then assertThatThrownBy(room::moveToNextRound) diff --git a/backend/src/test/resources/init-test.sql b/backend/src/test/resources/init-test.sql index e4da0c35..26992130 100644 --- a/backend/src/test/resources/init-test.sql +++ b/backend/src/test/resources/init-test.sql @@ -1,7 +1,7 @@ -INSERT INTO room (total_round, current_round, status) -VALUES (5, 2, 'PROGRESS'), - (5, 1, 'PROGRESS'), - (5, 1, 'PROGRESS'); +INSERT INTO room (total_round, current_round, time_limit, status) +VALUES (5, 2, 10000, 'PROGRESS'), + (5, 1, 10000, 'PROGRESS'), + (5, 1, 10000, 'PROGRESS'); INSERT INTO member (nickname, room_id, is_master) VALUES ('mohamedeu al katan', 1, true), From 2eae6cde8e27831bccd4d49c2e242ba6b488a41d Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Wed, 31 Jul 2024 16:18:37 +0900 Subject: [PATCH 0359/1013] =?UTF-8?q?feat:=20=EB=8C=80=EA=B8=B0=EB=B0=A9?= =?UTF-8?q?=20=EB=A9=A4=EB=B2=84=20=EC=A1=B0=ED=9A=8C=20DTO=EC=97=90=20?= =?UTF-8?q?=EB=B0=A9=EC=9D=98=20=EC=84=B8=ED=8C=85=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=B6=94=EA=B0=80=20#94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../balance/room/dto/RoomInfoResponse.java | 8 ++++---- .../{RoomSetting.java => RoomSettingResponse.java} | 3 ++- .../controller/balance/room/RoomControllerTest.java | 12 +++++++++--- .../service/balance/room/RoomServiceTest.java | 10 ++++++++-- 4 files changed, 23 insertions(+), 10 deletions(-) rename backend/src/main/java/ddangkong/controller/balance/room/dto/{RoomSetting.java => RoomSettingResponse.java} (56%) diff --git a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomInfoResponse.java b/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomInfoResponse.java index f2f3b220..2db0c7fa 100644 --- a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomInfoResponse.java +++ b/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomInfoResponse.java @@ -7,15 +7,15 @@ public record RoomInfoResponse( boolean isGameStart, - RoomSetting roomSetting, + RoomSettingResponse roomSetting, List members ) { public static RoomInfoResponse of(List members, Room room) { - List response = members.stream() + List membersResponse = members.stream() .map(MemberResponse::new) .toList(); - RoomSetting roomSetting = new RoomSetting(room.getTimeLimit()); + RoomSettingResponse roomSettingResponse = new RoomSettingResponse(room.getTotalRound(), room.getTimeLimit()); - return new RoomInfoResponse(room.isGameProgress(), roomSetting, response); + return new RoomInfoResponse(room.isGameProgress(), roomSettingResponse, membersResponse); } } diff --git a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSetting.java b/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSettingResponse.java similarity index 56% rename from backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSetting.java rename to backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSettingResponse.java index 9837b18f..035763ce 100644 --- a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSetting.java +++ b/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSettingResponse.java @@ -1,6 +1,7 @@ package ddangkong.controller.balance.room.dto; -public record RoomSetting( +public record RoomSettingResponse( + int totalRound, int timeLimit ) { } diff --git a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java index 08afa3b7..860e6f9c 100644 --- a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java @@ -1,6 +1,7 @@ package ddangkong.controller.balance.room; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; import ddangkong.controller.BaseControllerTest; import ddangkong.controller.balance.content.dto.BalanceContentResponse; @@ -19,10 +20,10 @@ class RoomControllerTest extends BaseControllerTest { @Nested - class 밸런스_게임_방_전체_멤버_조회 { + class 밸런스_게임_방_정보_조회 { @Test - void 게임_방_전체_멤버_조회() { + void 게임_방_정보_조회() { //when RoomInfoResponse actual = RestAssured.given() .when().get("/api/balances/rooms/1") @@ -31,7 +32,12 @@ class 밸런스_게임_방_전체_멤버_조회 { .extract().as(RoomInfoResponse.class); //then - Assertions.assertThat(actual.members()).hasSize(4); + assertAll( + () -> Assertions.assertThat(actual.members()).hasSize(4), + () -> Assertions.assertThat(actual.isGameStart()).isTrue(), + () -> Assertions.assertThat(actual.roomSetting().timeLimit()).isEqualTo(10000), + () -> Assertions.assertThat(actual.roomSetting().totalRound()).isEqualTo(5) + ); } } diff --git a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java index c9e65031..44b9bd96 100644 --- a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertAll; import ddangkong.controller.balance.content.dto.BalanceContentResponse; import ddangkong.controller.balance.member.dto.MemberResponse; @@ -33,8 +34,13 @@ class 게임_방_정보_조회 { // then RoomInfoResponse actual = roomService.findRoomInfo(room.roomId()); - Assertions.assertThat(actual.members()).hasSize(3); - Assertions.assertThat(actual.isGameStart()).isFalse(); + + assertAll( + () -> Assertions.assertThat(actual.members()).hasSize(3), + () -> Assertions.assertThat(actual.isGameStart()).isFalse(), + () -> Assertions.assertThat(actual.roomSetting().timeLimit()).isEqualTo(10000), + () -> Assertions.assertThat(actual.roomSetting().totalRound()).isEqualTo(5) + ); } } From ff6b575c08c5c87d09bf5e6920d9d89936940d8b Mon Sep 17 00:00:00 2001 From: jhon3242 Date: Wed, 31 Jul 2024 16:37:19 +0900 Subject: [PATCH 0360/1013] =?UTF-8?q?feat:=20API=20=EB=B0=B0=EC=97=B4=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EB=B3=80?= =?UTF-8?q?=EC=88=98=EB=AA=85,=20docs=20=EC=88=9C=EC=84=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20#85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/docs/asciidoc/room.adoc | 15 ++++++++------- .../balance/member/dto/MemberResponse.java | 2 +- .../balance/room/RoomDocumentationTest.java | 18 ++++++++++-------- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/backend/src/docs/asciidoc/room.adoc b/backend/src/docs/asciidoc/room.adoc index b65b14c4..9d0cea3c 100644 --- a/backend/src/docs/asciidoc/room.adoc +++ b/backend/src/docs/asciidoc/room.adoc @@ -3,6 +3,7 @@ === 방 생성 ==== curl + include::{snippets}/room/create/curl-request.adoc[] ==== request @@ -32,12 +33,12 @@ include::{snippets}/room/join/curl-request.adoc[] include::{snippets}/room/join/http-request.adoc[] +include::{snippets}/room/join/path-parameters.adoc[] + request fields include::{snippets}/room/join/request-fields.adoc[] -include::{snippets}/room/join/path-parameters.adoc[] - ==== response @@ -52,21 +53,21 @@ include::{snippets}/room/join/response-fields.adoc[] ==== curl -include::{snippets}/room/find/curl-request.adoc[] +include::{snippets}/room/memberSearch/curl-request.adoc[] ==== request -include::{snippets}/room/find/http-request.adoc[] +include::{snippets}/room/memberSearch/http-request.adoc[] -include::{snippets}/room/find/path-parameters.adoc[] +include::{snippets}/room/memberSearch/path-parameters.adoc[] ==== response -include::{snippets}/room/find/http-response.adoc[] +include::{snippets}/room/memberSearch/http-response.adoc[] response fields -include::{snippets}/room/find/response-fields.adoc[] +include::{snippets}/room/memberSearch/response-fields.adoc[] === 다음 라운드로 이동 diff --git a/backend/src/main/java/ddangkong/controller/balance/member/dto/MemberResponse.java b/backend/src/main/java/ddangkong/controller/balance/member/dto/MemberResponse.java index 4d60bc13..e2370e63 100644 --- a/backend/src/main/java/ddangkong/controller/balance/member/dto/MemberResponse.java +++ b/backend/src/main/java/ddangkong/controller/balance/member/dto/MemberResponse.java @@ -3,7 +3,7 @@ import ddangkong.domain.member.Member; public record MemberResponse( - Long id, + Long memberId, String nickname, boolean isMaster ) { diff --git a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java index 3c23fd10..c70c0fd5 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java @@ -34,6 +34,7 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; +import org.springframework.restdocs.payload.JsonFieldType; @WebMvcTest(RoomController.class) class RoomDocumentationTest extends BaseDocumentationTest { @@ -51,10 +52,10 @@ class 방_생성 { //given RoomJoinRequest request = new RoomJoinRequest("땅콩"); String content = objectMapper.writeValueAsString(request); - MemberResponse memberResponse = new MemberResponse(1L, "땅콩", true); - RoomJoinResponse response = new RoomJoinResponse(1L, memberResponse); //when + MemberResponse memberResponse = new MemberResponse(1L, "땅콩", true); + RoomJoinResponse response = new RoomJoinResponse(1L, memberResponse); when(roomService.createRoom(anyString())).thenReturn(response); //then @@ -69,7 +70,7 @@ class 방_생성 { ), responseFields( fieldWithPath("roomId").type(NUMBER).description("생성된 방 ID"), - fieldWithPath("member.id").type(NUMBER).description("멤버 ID"), + fieldWithPath("member.memberId").type(NUMBER).description("멤버 ID"), fieldWithPath("member.nickname").type(STRING).description("멤버 닉네임"), fieldWithPath("member.isMaster").type(BOOLEAN).description("방장 여부") ) @@ -107,7 +108,7 @@ class 방_참여 { ), responseFields( fieldWithPath("roomId").type(NUMBER).description("생성된 방 ID"), - fieldWithPath("member.id").type(NUMBER).description("멤버 ID"), + fieldWithPath("member.memberId").type(NUMBER).description("멤버 ID"), fieldWithPath("member.nickname").type(STRING).description("멤버 닉네임"), fieldWithPath("member.isMaster").type(BOOLEAN).description("방장 여부") ) @@ -134,14 +135,15 @@ class 방_전체_멤버_조회 { //then mockMvc.perform(get(ENDPOINT, 1L)) .andExpect(status().isOk()) - .andDo(document("room/find", + .andDo(document("room/memberSearch", pathParameters( parameterWithName("roomId").description("방 ID") ), responseFields( - fieldWithPath("members.[].memberId").type(NUMBER).description("멤버 ID"), - fieldWithPath("members.[].nickname").type(STRING).description("멤버 닉네임"), - fieldWithPath("members.[].isMaster").type(BOOLEAN).description("방장 여부") + fieldWithPath("members").type(JsonFieldType.ARRAY).description("방에 참여중 인원 목록"), + fieldWithPath("members[].memberId").type(NUMBER).description("멤버 ID"), + fieldWithPath("members[].nickname").type(STRING).description("멤버 닉네임"), + fieldWithPath("members[].isMaster").type(BOOLEAN).description("방장 여부") ) )); } From 365051f8f576cd44a33f6306cefbebd8904ccef6 Mon Sep 17 00:00:00 2001 From: jhon3242 Date: Wed, 31 Jul 2024 16:42:31 +0900 Subject: [PATCH 0361/1013] =?UTF-8?q?merge:=20RoomMemberResponse=20?= =?UTF-8?q?=EC=B6=A9=EB=8F=8C=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0=20?= =?UTF-8?q?#85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - RoomMemberResponse -> MembersResponse 로 변경하여 문제 해결 --- .../balance/room/RoomDocumentationTest.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java index c70c0fd5..c090d143 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java @@ -19,12 +19,11 @@ import ddangkong.controller.balance.content.dto.BalanceContentResponse; import ddangkong.controller.balance.member.dto.MemberResponse; +import ddangkong.controller.balance.member.dto.MembersResponse; import ddangkong.controller.balance.option.dto.BalanceOptionResponse; import ddangkong.controller.balance.room.RoomController; import ddangkong.controller.balance.room.dto.RoomJoinRequest; import ddangkong.controller.balance.room.dto.RoomJoinResponse; -import ddangkong.controller.balance.room.dto.RoomMemberResponse; -import ddangkong.controller.balance.room.dto.RoomMembersResponse; import ddangkong.documentation.BaseDocumentationTest; import ddangkong.domain.balance.content.Category; import ddangkong.service.balance.room.RoomService; @@ -124,9 +123,9 @@ class 방_전체_멤버_조회 { @Test void 방_전체_멤버를_조회한다() throws Exception{ //given - RoomMembersResponse response = new RoomMembersResponse(List.of( - new RoomMemberResponse(1L, "땅콩", true), - new RoomMemberResponse(2L, "타콩", false) + MembersResponse response = new MembersResponse(List.of( + new MemberResponse(1L, "땅콩", true), + new MemberResponse(2L, "타콩", false) )); //when From 924c09b76c09436d8282f8dc05a0ec5eb785e30a Mon Sep 17 00:00:00 2001 From: novice0840 Date: Wed, 31 Jul 2024 16:53:04 +0900 Subject: [PATCH 0362/1013] =?UTF-8?q?feat:=20=EB=8C=80=EA=B8=B0=EB=B0=A9?= =?UTF-8?q?=20UI=20=EC=9E=91=EC=97=85=20=EC=99=84=EB=A3=8C=20#92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadyMembersContainer.styled.ts | 52 ++++++++++++++ .../ReadyMembersContainer.tsx | 68 ++++++++++++++++++- .../src/pages/ReadyPage/ReadyPage.styled.ts | 7 -- frontend/src/pages/ReadyPage/ReadyPage.tsx | 18 +---- 4 files changed, 119 insertions(+), 26 deletions(-) diff --git a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.styled.ts b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.styled.ts index 5f772e68..4025c3ed 100644 --- a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.styled.ts +++ b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.styled.ts @@ -7,4 +7,56 @@ export const readyMembersContainerLayout = css` padding: 2rem 3rem 0; background-color: ${Theme.color.peanut300}; + + position: relative; + + border-radius: 2rem; + + overflow-y: scroll; + + font-weight: 600; + + /* 스크롤바 숨기기 */ + scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* IE and Edge */ + + &::-webkit-scrollbar { + display: none; /* Chrome, Safari, Opera */ + } +`; + +export const totalNumber = css` + font-weight: 900; + font-size: 1.2rem; + padding-left: 2rem; +`; + +export const memberList = css` + display: flex; + flex-direction: column; + gap: 2rem; +`; + +export const memberItem = css` + display: flex; + gap: 2rem; + align-items: center; +`; + +export const profileBox = css` + width: 3.6rem; + height: 3.6rem; + background-color: white; + + border-radius: 50%; + + display: flex; + justify-content: center; + align-items: center; +`; + +export const memberStatus = css` + display: flex; + flex: 1; + justify-content: space-between; `; diff --git a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx index e5f99eed..c22d1715 100644 --- a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx +++ b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx @@ -1,7 +1,71 @@ -import { readyMembersContainerLayout } from './ReadyMembersContainer.styled'; +import { + readyMembersContainerLayout, + totalNumber, + memberItem, + memberList, + profileBox, + memberStatus, +} from './ReadyMembersContainer.styled'; +import { nickname } from '../GameResultItem/GameResultItem.styled'; + +const example = { + isGameStart: false, + roomSettings: { + totalRound: 5, + timeLimit: 10000, + }, + members: [ + { + memberId: 1, + nickname: '든콩', + isMaster: true, + }, + { + memberId: 2, + nickname: '프콩', + isMaster: false, + }, + { + memberId: 3, + nickname: '프콩', + isMaster: false, + }, + { + memberId: 4, + nickname: '프콩', + isMaster: false, + }, + { + memberId: 5, + nickname: '프콩', + isMaster: false, + }, + ], +}; const ReadyMembersContainer = () => { - return
    대기방 컨테이너
    ; + return ( + <> +
    총 인원 5명
    +
    +
      +
    • +
      +
      +
      초대하기
      +
    • + {example.members.map((member) => ( +
    • +
      +
      +
      + {member.nickname} + {member.isMaster && 왕관} +
      +
    • + ))} +
    +
    + + ); }; export default ReadyMembersContainer; diff --git a/frontend/src/pages/ReadyPage/ReadyPage.styled.ts b/frontend/src/pages/ReadyPage/ReadyPage.styled.ts index 84b7ae3a..033b8756 100644 --- a/frontend/src/pages/ReadyPage/ReadyPage.styled.ts +++ b/frontend/src/pages/ReadyPage/ReadyPage.styled.ts @@ -6,10 +6,3 @@ export const readyPageLayout = css` gap: 2rem; padding: 0 2.4rem; `; - -export const totalNumber = css` - padding-left: 2rem; - - font-weight: 500; - font-size: 1.2rem; -`; diff --git a/frontend/src/pages/ReadyPage/ReadyPage.tsx b/frontend/src/pages/ReadyPage/ReadyPage.tsx index 364025ad..76e05045 100644 --- a/frontend/src/pages/ReadyPage/ReadyPage.tsx +++ b/frontend/src/pages/ReadyPage/ReadyPage.tsx @@ -1,30 +1,14 @@ import React from 'react'; -import { readyPageLayout, totalNumber } from './ReadyPage.styled'; +import { readyPageLayout } from './ReadyPage.styled'; import CategoryContainer from '@/components/CategoryContainer/CategoryContainer'; import ReadyMembersContainer from '@/components/ReadyMembersContainer/ReadyMembersContainer'; -const example = { - members: [ - { - memberId: 1, - nickname: '든콩', - isMaster: true, - }, - { - memberId: 2, - nickname: '프콩', - isMaster: false, - }, - ], -}; - const GameWaitPage = () => { return (
    -
    총 인원 5명
    ); From 4e53d2ad7452c414c2bf02df3a25b118512b60d3 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Wed, 31 Jul 2024 16:54:54 +0900 Subject: [PATCH 0363/1013] =?UTF-8?q?fix:=20css=20=EC=88=9C=EC=84=9C=20?= =?UTF-8?q?=EC=A1=B0=EC=A0=95=20#92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadyMembersContainer.styled.ts | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.styled.ts b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.styled.ts index 4025c3ed..4d950f8c 100644 --- a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.styled.ts +++ b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.styled.ts @@ -3,19 +3,17 @@ import { css } from '@emotion/react'; import { Theme } from '@/styles/Theme'; export const readyMembersContainerLayout = css` + position: relative; height: 25rem; padding: 2rem 3rem 0; + border-radius: 2rem; background-color: ${Theme.color.peanut300}; - position: relative; - - border-radius: 2rem; + font-weight: 600; overflow-y: scroll; - font-weight: 600; - /* 스크롤바 숨기기 */ scrollbar-width: none; /* Firefox */ -ms-overflow-style: none; /* IE and Edge */ @@ -26,9 +24,10 @@ export const readyMembersContainerLayout = css` `; export const totalNumber = css` + padding-left: 2rem; + font-weight: 900; font-size: 1.2rem; - padding-left: 2rem; `; export const memberList = css` @@ -39,20 +38,19 @@ export const memberList = css` export const memberItem = css` display: flex; - gap: 2rem; align-items: center; + gap: 2rem; `; export const profileBox = css` + display: flex; + justify-content: center; + align-items: center; width: 3.6rem; height: 3.6rem; - background-color: white; - border-radius: 50%; - display: flex; - justify-content: center; - align-items: center; + background-color: white; `; export const memberStatus = css` From 9ce9064f4349464fe75fb6416e7aea0d648cfc61 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Wed, 31 Jul 2024 17:01:08 +0900 Subject: [PATCH 0364/1013] =?UTF-8?q?style:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=AA=85=20=EB=8F=99=EC=82=AC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20#94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ddangkong/service/balance/room/RoomServiceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java index 44b9bd96..01671c4e 100644 --- a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java @@ -26,7 +26,7 @@ class RoomServiceTest extends BaseServiceTest { class 게임_방_정보_조회 { @Test - void 대기중인_게임_방_정보_조회() { + void 게임_방_정보를_조회한다() { // when RoomJoinResponse room = roomService.createRoom("방장"); roomService.joinRoom("멤버1", room.roomId()); From 6d29a797c4334ced49d200ed8b294419c5b9c47b Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Wed, 31 Jul 2024 17:38:08 +0900 Subject: [PATCH 0365/1013] =?UTF-8?q?style:=20=EA=B8=B0=EB=B3=B8=20?= =?UTF-8?q?=EC=8B=9C=EA=B0=84=20=EC=A0=9C=ED=95=9C=20msec=20=EC=83=81?= =?UTF-8?q?=EC=88=98=20=EB=B3=80=EC=88=98=EB=AA=85=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?#94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/main/java/ddangkong/domain/balance/room/Room.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/Room.java b/backend/src/main/java/ddangkong/domain/balance/room/Room.java index 889da399..57b73020 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/Room.java @@ -18,7 +18,7 @@ public class Room { private static final int DEFAULT_TOTAL_ROUND = 5; - private static final int DEFAULT_TIME_LIMIT = 10000; + private static final int DEFAULT_TIME_LIMIT_MSEC = 10000; private static final int START_ROUND = 1; @Id @@ -39,7 +39,7 @@ public class Room { private RoomStatus status; public static Room createNewRoom() { - return new Room(DEFAULT_TOTAL_ROUND, START_ROUND, DEFAULT_TIME_LIMIT, RoomStatus.READY); + return new Room(DEFAULT_TOTAL_ROUND, START_ROUND, DEFAULT_TIME_LIMIT_MSEC, RoomStatus.READY); } public Room(int totalRound, int currentRound, int timeLimit, RoomStatus status) { From 97c0bf62e895d37ca6cc5c29c199f63b5e815eaf Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Wed, 31 Jul 2024 17:43:13 +0900 Subject: [PATCH 0366/1013] =?UTF-8?q?style:=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=82=AC=EC=9A=A9=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EA=B0=92=20final=20=EC=A0=9C=EA=B1=B0=20=EB=B0=8F=20=EC=B9=B4?= =?UTF-8?q?=EB=A9=9C=EC=BC=80=EC=9D=B4=EC=8A=A4=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20#94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/java/ddangkong/domain/balance/room/RoomTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java index 8a2ec7e5..0e2de294 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java @@ -30,10 +30,10 @@ class 다음_라운드로_이동 { @Test void 마지막_라운드_일_경우_예외를_던진다() { // given - final int TOTAL_ROUND = 5; - final int CURRENT_ROUND = 5; - final int TIME_LIMIT = 10000; - Room room = new Room(TOTAL_ROUND, CURRENT_ROUND, TIME_LIMIT, RoomStatus.PROGRESS); + int totalRound = 5; + int currentRound = 5; + int timeLimit = 10000; + Room room = new Room(totalRound, currentRound, timeLimit, RoomStatus.PROGRESS); // when & then assertThatThrownBy(room::moveToNextRound) From f4d6f9757b44758870fed16ddbb7f642ccd8a62b Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Wed, 31 Jul 2024 17:46:30 +0900 Subject: [PATCH 0367/1013] =?UTF-8?q?refactor:=20isGameProgress=20?= =?UTF-8?q?=EC=B2=B4=ED=81=AC=20=EB=A1=9C=EC=A7=81=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=EA=B0=92=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81=20#94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ddangkong/domain/balance/room/RoomStatus.java | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomStatus.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomStatus.java index 751cfc18..4397dd57 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomStatus.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomStatus.java @@ -1,18 +1,12 @@ package ddangkong.domain.balance.room; public enum RoomStatus { - READY(false), - PROGRESS(true), - FINISH(false), + READY, + PROGRESS, + FINISH, ; - private final boolean isGameProgress; - - RoomStatus(boolean isGameProgress) { - this.isGameProgress = isGameProgress; - } - public boolean isGameProgress() { - return isGameProgress; + return this == PROGRESS; } } From d89ac1c640745977b52cfebc05a4e22b03f528b3 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Wed, 31 Jul 2024 17:50:07 +0900 Subject: [PATCH 0368/1013] =?UTF-8?q?style:=20=ED=81=B0=20=EC=A0=95?= =?UTF-8?q?=EC=88=98=EA=B0=92=EC=97=90=20=EC=96=B8=EB=8D=94=EC=8A=A4?= =?UTF-8?q?=EC=BD=94=EC=96=B4=20=ED=91=9C=EA=B8=B0=EB=B2=95=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EC=97=AC=20=EA=B0=80=EB=8F=85=EC=84=B1=20?= =?UTF-8?q?=ED=96=A5=EC=83=81=20#94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/main/java/ddangkong/domain/balance/room/Room.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/Room.java b/backend/src/main/java/ddangkong/domain/balance/room/Room.java index 57b73020..f2d47953 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/Room.java @@ -18,7 +18,7 @@ public class Room { private static final int DEFAULT_TOTAL_ROUND = 5; - private static final int DEFAULT_TIME_LIMIT_MSEC = 10000; + private static final int DEFAULT_TIME_LIMIT_MSEC = 10_000; private static final int START_ROUND = 1; @Id From 4de626bc40c7424723d73cd0fc444e22b9dbc889 Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 31 Jul 2024 17:54:38 +0900 Subject: [PATCH 0369/1013] =?UTF-8?q?refactor:=20=EC=8A=A4=ED=83=80?= =?UTF-8?q?=EC=9D=BC=20=EC=86=8D=EC=84=B1=20=EB=B3=B5=EC=9B=90=20auto?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95=20#60?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/Modal/hooks/useDisableBackgroundScroll.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend/src/components/common/Modal/hooks/useDisableBackgroundScroll.ts b/frontend/src/components/common/Modal/hooks/useDisableBackgroundScroll.ts index db53d785..ccd6004c 100644 --- a/frontend/src/components/common/Modal/hooks/useDisableBackgroundScroll.ts +++ b/frontend/src/components/common/Modal/hooks/useDisableBackgroundScroll.ts @@ -3,11 +3,10 @@ import { useEffect } from 'react'; const useDisableBackgroundScroll = (isOpen: boolean) => { useEffect(() => { if (isOpen) { - const originalOverflow = window.getComputedStyle(document.body).overflow; document.body.style.overflow = 'hidden'; return () => { - document.body.style.overflow = originalOverflow; + document.body.style.overflow = 'auto'; }; } }, [isOpen]); From 53c41b80d0684ad1203f6ca7fda14ec4bfe5b8ae Mon Sep 17 00:00:00 2001 From: jhon3242 Date: Wed, 31 Jul 2024 17:59:01 +0900 Subject: [PATCH 0370/1013] =?UTF-8?q?feat:=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80=20#96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/balance/room/RoomContent.java | 9 +++++++++ .../service/balance/vote/BalanceVoteService.java | 15 +++++++++++++++ backend/src/test/resources/init-test.sql | 10 +++++----- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java index 22ab7f88..66caf260 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java @@ -11,9 +11,11 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; +import java.time.LocalDateTime; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import org.springframework.data.annotation.CreatedDate; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -35,6 +37,13 @@ public class RoomContent extends BaseEntity { @Column(nullable = false) private int round; + @Column(nullable = false) + private LocalDateTime roundEndedAt; + + public boolean isRoundOver(LocalDateTime currentTime) { + return roundEndedAt.isAfter(currentTime); + } + public Long getContentId() { return balanceContent.getId(); } diff --git a/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java b/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java index 3650707a..aec899af 100644 --- a/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java +++ b/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java @@ -19,6 +19,7 @@ import ddangkong.domain.member.Member; import ddangkong.domain.member.MemberRepository; import ddangkong.exception.BadRequestException; +import java.time.LocalDateTime; import java.util.List; import java.util.Objects; import lombok.RequiredArgsConstructor; @@ -43,6 +44,7 @@ public class BalanceVoteService { @Transactional public BalanceVoteResponse createBalanceVote(BalanceVoteRequest request, Long roomId, Long contentId) { + validateVoteTime(roomId); BalanceOption balanceOption = findValidOption(request.optionId(), contentId); Member member = findValidMember(request.memberId(), roomId); @@ -51,6 +53,19 @@ public BalanceVoteResponse createBalanceVote(BalanceVoteRequest request, Long ro return new BalanceVoteResponse(savedBalanceVote); } + private void validateVoteTime(Long roomId) { + RoomContent roomContent = findValidRoomContent(roomId); + if (roomContent.isRoundOver(LocalDateTime.now())) { + throw new BadRequestException("이미 종료된 라운드는 투표할 수 없습니다."); + } + } + + private RoomContent findValidRoomContent(Long roomId) { + Room room = roomRepository.getById(roomId); + return roomContentRepository.findByRoomAndRound(room, room.getCurrentRound()) + .orElseThrow(() -> new BadRequestException("해당 방의 현재 진행중인 질문이 존재하지 않습니다.")); + } + private BalanceOption findValidOption(Long optionId, Long contentId) { return balanceOptionRepository.findByIdAndBalanceContentId(optionId, contentId) .orElseThrow(() -> new BadRequestException("해당 질문의 선택지가 존재하지 않습니다.")); diff --git a/backend/src/test/resources/init-test.sql b/backend/src/test/resources/init-test.sql index b570596a..a28b7140 100644 --- a/backend/src/test/resources/init-test.sql +++ b/backend/src/test/resources/init-test.sql @@ -16,11 +16,11 @@ VALUES ('EXAMPLE', '민초 vs 반민초'), ('EXAMPLE', '월 200 백수 vs 월 500 직장인'), ('EXAMPLE', '다음 중 여행가고 싶은 곳은?'); -INSERT INTO room_content (room_id, balance_content_id, round, created_at) -VALUES (1, 2, 1, '2024-07-18 19:50:00.000'), - (1, 1, 2, '2024-07-18 20:00:00.000'), - (1, 3, 3, '2024-07-18 20:00:00.000'), - (3, 1, 1, '2024-07-18 19:51:00.000'); +INSERT INTO room_content (room_id, balance_content_id, round, created_at, round_ended_at) +VALUES (1, 2, 1, '2024-07-18 19:50:00.000', '2099-12-31 23:59:59.999'), + (1, 1, 2, '2024-07-18 20:00:00.000', '2099-12-31 23:59:59.999'), + (1, 3, 3, '2024-07-18 20:00:00.000', '2099-12-31 23:59:59.999'), + (3, 1, 1, '2024-07-18 19:51:00.000', '2099-12-31 23:59:59.999'); INSERT INTO balance_option (name, balance_content_id) VALUES ('민초', 1), From 86a90266fe3ab93cf08b1193289b4c598bebfce3 Mon Sep 17 00:00:00 2001 From: jhon3242 Date: Wed, 31 Jul 2024 18:01:26 +0900 Subject: [PATCH 0371/1013] =?UTF-8?q?style:=20given,=20when=20=EA=B8=B0?= =?UTF-8?q?=EC=A4=80=20=EC=A0=95=EB=A6=BD=20#85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - when 에서는 테스트하는 동작 자체만 넣는것으로 정리 --- .../documentation/balance/room/RoomDocumentationTest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java index c090d143..0a10855b 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java @@ -88,11 +88,9 @@ class 방_참여 { RoomJoinRequest request = new RoomJoinRequest("타콩"); RoomJoinResponse response = new RoomJoinResponse(1L, new MemberResponse(2L, "타콩", false)); String content = objectMapper.writeValueAsString(request); - - //when when(roomService.joinRoom(anyString(), anyLong())).thenReturn(response); - //then + //when & then mockMvc.perform(post(ENDPOINT, 1L) .content(content) .contentType(MediaType.APPLICATION_JSON) From 244fe82d723389623faa2c81ff7e4ea80971d9d5 Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 31 Jul 2024 18:09:16 +0900 Subject: [PATCH 0372/1013] =?UTF-8?q?refactor:=20=EC=8A=A4=ED=86=A0?= =?UTF-8?q?=EB=A6=AC=EB=B6=81=20=EB=B6=88=20=ED=95=84=EC=9A=94=ED=95=9C=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=82=AD=EC=A0=9C=20#60?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/common/Modal/Modal.stories.tsx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/frontend/src/components/common/Modal/Modal.stories.tsx b/frontend/src/components/common/Modal/Modal.stories.tsx index 24177a3a..3ee19159 100644 --- a/frontend/src/components/common/Modal/Modal.stories.tsx +++ b/frontend/src/components/common/Modal/Modal.stories.tsx @@ -8,10 +8,6 @@ import CloseIcon from '@/assets/images/closeIcon.png'; const meta = { title: 'Modal', component: Modal, - parameters: { - argTypes: {}, - actions: { argTypesRegex: '^on.*' }, - }, argTypes: { isOpen: { control: 'boolean', @@ -78,7 +74,6 @@ export const 이미지_버튼이_있는_모달: Story = { args: { isOpen: true, position: 'center', - onClose: fn(), }, parameters: { docs: { @@ -104,7 +99,6 @@ export const 텍스트_버튼이_있는_모달: Story = { args: { isOpen: true, position: 'center', - onClose: fn(), }, parameters: { docs: { @@ -133,7 +127,6 @@ export const 이미지_버튼과_텍스트_버튼이_있는_모달: Story = { args: { isOpen: true, position: 'center', - onClose: fn(), }, parameters: { docs: { From 643485bcef4fc2043820a807d0de6bb75636ce91 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Wed, 31 Jul 2024 18:29:07 +0900 Subject: [PATCH 0373/1013] =?UTF-8?q?feat:=20common=20button=EC=97=90=20bo?= =?UTF-8?q?ttom=20=EC=86=8D=EC=84=B1=20=EC=B6=94=EA=B0=80=20#92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/common/Button/Button.styled.ts | 18 +++++++++++++++++- .../src/components/common/Button/Button.tsx | 4 +++- frontend/src/pages/ReadyPage/ReadyPage.tsx | 8 ++++++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/common/Button/Button.styled.ts b/frontend/src/components/common/Button/Button.styled.ts index d4a85e13..b4005d8a 100644 --- a/frontend/src/components/common/Button/Button.styled.ts +++ b/frontend/src/components/common/Button/Button.styled.ts @@ -10,9 +10,16 @@ interface ButtonLayoutProps { size?: 'small' | 'medium' | 'large'; radius?: 'small' | 'medium' | 'large'; fontSize?: 'small' | 'medium' | 'large'; + bottom?: boolean; } -export const buttonLayout = ({ disabled, size, radius, fontSize }: ButtonLayoutProps) => css` +export const buttonLayout = ({ + disabled, + size, + radius, + fontSize, + bottom, +}: ButtonLayoutProps) => css` display: flex; justify-content: center; @@ -30,6 +37,15 @@ export const buttonLayout = ({ disabled, size, radius, fontSize }: ButtonLayoutP &:disabled { background-color: ${Theme.color.peanut300}; } + + ${bottom && + css` + position: fixed; + left: 50%; + transform: translateX(-50%); + bottom: 0; + max-width: 32rem; + `} `; export const bottomButtonLayout = css` diff --git a/frontend/src/components/common/Button/Button.tsx b/frontend/src/components/common/Button/Button.tsx index 893bbcfb..a8309f6b 100644 --- a/frontend/src/components/common/Button/Button.tsx +++ b/frontend/src/components/common/Button/Button.tsx @@ -10,6 +10,7 @@ interface ButtonProps extends ButtonHTMLAttributes { size?: 'small' | 'medium' | 'large'; radius?: 'small' | 'medium' | 'large'; fontSize?: 'small' | 'medium' | 'large'; + bottom?: boolean; } const Button: React.FC = ({ @@ -19,13 +20,14 @@ const Button: React.FC = ({ size, radius, fontSize, + bottom, ...props }) => { return ( ); }; From 8785194d425320ebd9277b991184a0fdf645d937 Mon Sep 17 00:00:00 2001 From: useon Date: Thu, 1 Aug 2024 00:08:59 +0900 Subject: [PATCH 0386/1013] =?UTF-8?q?refactor:=20=EB=8B=A4=EB=A5=B8=20?= =?UTF-8?q?=EC=9A=94=EC=86=8C=20=EC=9C=84=EC=97=90=20=ED=91=9C=EC=8B=9C?= =?UTF-8?q?=ED=95=98=EA=B8=B0=20=EC=9C=84=ED=95=B4=20createPotal=EC=9D=84?= =?UTF-8?q?=20=EC=82=AC=EC=9A=A9=ED=95=98=EC=97=AC=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?#60?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/common/Modal/Modal.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/common/Modal/Modal.tsx b/frontend/src/components/common/Modal/Modal.tsx index e3f3ddb9..d9786eaf 100644 --- a/frontend/src/components/common/Modal/Modal.tsx +++ b/frontend/src/components/common/Modal/Modal.tsx @@ -1,4 +1,5 @@ import React, { ButtonHTMLAttributes, HTMLAttributes, useRef } from 'react'; +import ReactDOM from 'react-dom'; import useDisableBackgroundScroll from './hooks/useDisableBackgroundScroll'; import useModalEscClose from './hooks/useModalEscClose'; @@ -39,7 +40,7 @@ const Modal = ({ children, isOpen, onClose, position = 'center', ...restProps }: if (!isOpen) return null; - return ( + const modalContent = ( /* eslint jsx-a11y/no-static-element-interactions: "off" */ // 모달을 제외한 영역을 클릭시 모달이 꺼지도록 설정하기 위해 설정함
    @@ -48,6 +49,8 @@ const Modal = ({ children, isOpen, onClose, position = 'center', ...restProps }:
    ); + + return ReactDOM.createPortal(modalContent, document.body); }; interface ModalHeaderProps extends React.PropsWithChildren> {} From a69a747498e7af5918a6da505dd2796f488d3e5d Mon Sep 17 00:00:00 2001 From: novice0840 Date: Thu, 1 Aug 2024 12:37:34 +0900 Subject: [PATCH 0387/1013] =?UTF-8?q?feat:=20=EB=B0=A9=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20API=20=ED=95=A8=EC=88=98=20=EC=B6=94=EA=B0=80=20#92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/room.ts | 49 +++++++++++++++++++ frontend/src/constants/url.ts | 2 + .../src/pages/NicknamePage/NicknamePage.tsx | 10 +++- 3 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 frontend/src/apis/room.ts diff --git a/frontend/src/apis/room.ts b/frontend/src/apis/room.ts new file mode 100644 index 00000000..a797fa64 --- /dev/null +++ b/frontend/src/apis/room.ts @@ -0,0 +1,49 @@ +import fetcher from './fetcher'; + +import { nickname } from '@/components/GameResultItem/GameResultItem.styled'; +import { API_URL } from '@/constants/url'; + +// 방 만들기 +export const makeRoom = async (nickname: string) => { + const res = await fetcher.post({ + url: API_URL.room, + headers: { + 'Content-Type': `application/json`, + }, + body: { + nickname, + }, + }); + + const data = await res.json(); + + return data; +}; + +// 방 참여하기 +export const enterRoom = async (roomId: number, nickname: string) => { + const res = await fetcher.post({ + url: API_URL.roomMembers(roomId), + headers: { + 'Content-Type': `application/json`, + }, + body: { + nickname, + }, + }); + + const data = await res.json(); + + return data; +}; + +// 방 전체 멤버 조회 +export const getMembers = async (roomId: number) => { + const res = await fetcher.get({ + url: API_URL.roomMembers(roomId), + }); + + const data = await res.json(); + + return data; +}; diff --git a/frontend/src/constants/url.ts b/frontend/src/constants/url.ts index d313c6a3..3c04d4e4 100644 --- a/frontend/src/constants/url.ts +++ b/frontend/src/constants/url.ts @@ -8,6 +8,8 @@ export const API_URL = { `${BASE_URL}/api/balances/rooms/${roomId}/contents/${contentId}/vote-result`, moveNextRound: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/contents`, finalResult: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/final`, + room: `${BASE_URL}/api/balances/rooms`, + roomMembers: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/members`, }; export const MOCK_API_URL = { diff --git a/frontend/src/pages/NicknamePage/NicknamePage.tsx b/frontend/src/pages/NicknamePage/NicknamePage.tsx index 94d0e7d9..e109c201 100644 --- a/frontend/src/pages/NicknamePage/NicknamePage.tsx +++ b/frontend/src/pages/NicknamePage/NicknamePage.tsx @@ -1,5 +1,5 @@ import { useRef } from 'react'; -import { useLocation } from 'react-router-dom'; +import { useLocation, useNavigate } from 'react-router-dom'; import { profile, nickname, nicknameInputWrapper, nicknameInput } from './NicknamePage.styled'; @@ -10,6 +10,12 @@ import { createRandomNickname } from '@/utils/nickname'; const NicknamePage = () => { const randomNickname = createRandomNickname(); const nicknameInputRef = useRef(null); + const navigate = useNavigate(); + + const goToReadyPage = () => { + navigate('/ready', { state: { isMaster: true } }); + }; + const { state } = useLocation(); const handleClick = () => { @@ -28,7 +34,7 @@ const NicknamePage = () => { ref={nicknameInputRef} /> - + ); }; From e37a646b3ece5b0f64a4526ca275cff4c6314670 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 1 Aug 2024 13:04:50 +0900 Subject: [PATCH 0388/1013] =?UTF-8?q?test:=20API=20=EC=8A=A4=ED=8E=99=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=97=90=20=EB=94=B0=EB=A5=B8=20RestDocs=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20#94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/docs/asciidoc/room.adoc | 12 +++---- backend/src/main/resources/sql/data-dev.sql | 4 +-- .../balance/room/RoomDocumentationTest.java | 32 ++++++++++++------- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/backend/src/docs/asciidoc/room.adoc b/backend/src/docs/asciidoc/room.adoc index 9d0cea3c..1f08bec5 100644 --- a/backend/src/docs/asciidoc/room.adoc +++ b/backend/src/docs/asciidoc/room.adoc @@ -53,21 +53,21 @@ include::{snippets}/room/join/response-fields.adoc[] ==== curl -include::{snippets}/room/memberSearch/curl-request.adoc[] +include::{snippets}/room/info/curl-request.adoc[] ==== request -include::{snippets}/room/memberSearch/http-request.adoc[] +include::{snippets}/room/info/http-request.adoc[] -include::{snippets}/room/memberSearch/path-parameters.adoc[] +include::{snippets}/room/info/path-parameters.adoc[] ==== response -include::{snippets}/room/memberSearch/http-response.adoc[] +include::{snippets}/room/info/http-response.adoc[] response fields -include::{snippets}/room/memberSearch/response-fields.adoc[] +include::{snippets}/room/info/response-fields.adoc[] === 다음 라운드로 이동 @@ -87,4 +87,4 @@ include::{snippets}/room/next/http-response.adoc[] response fields -include::{snippets}/room/next/response-fields.adoc[] \ No newline at end of file +include::{snippets}/room/next/response-fields.adoc[] diff --git a/backend/src/main/resources/sql/data-dev.sql b/backend/src/main/resources/sql/data-dev.sql index 59f8b408..72d462bb 100644 --- a/backend/src/main/resources/sql/data-dev.sql +++ b/backend/src/main/resources/sql/data-dev.sql @@ -19,8 +19,8 @@ VALUES ('민초', 1), ('어떻게 죽을 지 알기', 5); -INSERT INTO room(total_round, current_round) -VALUES (5, 1); +INSERT INTO room(total_round, current_round, time_limit, status) +VALUES (5, 1, 10000, 'READY'); INSERT INTO room_content(room_id, balance_content_id, round, created_at) diff --git a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java index 0a10855b..9851fe7c 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java @@ -19,11 +19,12 @@ import ddangkong.controller.balance.content.dto.BalanceContentResponse; import ddangkong.controller.balance.member.dto.MemberResponse; -import ddangkong.controller.balance.member.dto.MembersResponse; import ddangkong.controller.balance.option.dto.BalanceOptionResponse; import ddangkong.controller.balance.room.RoomController; +import ddangkong.controller.balance.room.dto.RoomInfoResponse; import ddangkong.controller.balance.room.dto.RoomJoinRequest; import ddangkong.controller.balance.room.dto.RoomJoinResponse; +import ddangkong.controller.balance.room.dto.RoomSettingResponse; import ddangkong.documentation.BaseDocumentationTest; import ddangkong.domain.balance.content.Category; import ddangkong.service.balance.room.RoomService; @@ -114,29 +115,38 @@ class 방_참여 { } @Nested - class 방_전체_멤버_조회 { + class 방_정보_조회 { - private static final String ENDPOINT = "/api/balances/rooms/{roomId}/members"; + private static final String ENDPOINT = "/api/balances/rooms/{roomId}"; @Test - void 방_전체_멤버를_조회한다() throws Exception{ + void 방_정보를_조회한다() throws Exception { //given - MembersResponse response = new MembersResponse(List.of( - new MemberResponse(1L, "땅콩", true), - new MemberResponse(2L, "타콩", false) - )); + int totalRound = 5; + int timeLimit = 10000; + RoomInfoResponse response = new RoomInfoResponse( + false, + new RoomSettingResponse(totalRound, timeLimit), + List.of( + new MemberResponse(1L, "땅콩", true), + new MemberResponse(2L, "타콩", false) + )); //when - when(roomService.findAllRoomMember(anyLong())).thenReturn(response); + when(roomService.findRoomInfo(anyLong())).thenReturn(response); //then mockMvc.perform(get(ENDPOINT, 1L)) .andExpect(status().isOk()) - .andDo(document("room/memberSearch", + .andDo(document("room/info", pathParameters( parameterWithName("roomId").description("방 ID") ), responseFields( + fieldWithPath("isGameStart").type(BOOLEAN).description("게임 시작 여부"), + fieldWithPath("roomSetting").type(JsonFieldType.OBJECT).description("현재 방 설정 값"), + fieldWithPath("roomSetting.totalRound").type(NUMBER).description("전체 라운드"), + fieldWithPath("roomSetting.timeLimit").type(NUMBER).description("라운드 당 시간제한(ms)"), fieldWithPath("members").type(JsonFieldType.ARRAY).description("방에 참여중 인원 목록"), fieldWithPath("members[].memberId").type(NUMBER).description("멤버 ID"), fieldWithPath("members[].nickname").type(STRING).description("멤버 닉네임"), @@ -152,7 +162,7 @@ class 다음_라운드로_이동 { private static final String ENDPOINT = "/api/balances/rooms/{roomId}/contents"; @Test - void 다음_라운드로_이동한다() throws Exception{ + void 다음_라운드로_이동한다() throws Exception { //given BalanceOptionResponse firstOption = new BalanceOptionResponse(3L, "10년 동안 한 사람과 연애한 애인"); BalanceOptionResponse secondOption = new BalanceOptionResponse(4L, "1년 동안 다섯 사람과 연애한 애인"); From 8fbabe26ecbb79e5902dd807103bed1709e8a586 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 1 Aug 2024 13:06:10 +0900 Subject: [PATCH 0389/1013] =?UTF-8?q?fix:=20Docs=20=EB=B0=A9=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=A1=B0=ED=9A=8C=20API=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20#94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/docs/asciidoc/room.adoc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/backend/src/docs/asciidoc/room.adoc b/backend/src/docs/asciidoc/room.adoc index 1f08bec5..92361ad5 100644 --- a/backend/src/docs/asciidoc/room.adoc +++ b/backend/src/docs/asciidoc/room.adoc @@ -22,7 +22,6 @@ response fields include::{snippets}/room/create/response-fields.adoc[] - === 방 참여 ==== curl @@ -39,7 +38,6 @@ request fields include::{snippets}/room/join/request-fields.adoc[] - ==== response include::{snippets}/room/join/http-response.adoc[] @@ -48,8 +46,7 @@ response fields include::{snippets}/room/join/response-fields.adoc[] - -=== 방 멤버 조회 +=== 방 정보 조회 ==== curl From 30718fd2b13af7b708eccb7588360eed4aa566df Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 1 Aug 2024 13:11:30 +0900 Subject: [PATCH 0390/1013] =?UTF-8?q?fix:=20=EA=B8=B0=EB=B3=B8=20=EC=8B=9C?= =?UTF-8?q?=EA=B0=84=20=EC=A0=9C=ED=95=9C=2030=EC=B4=88=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20#94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/ddangkong/domain/balance/room/Room.java | 2 +- backend/src/main/resources/sql/data-dev.sql | 2 +- .../controller/balance/room/RoomControllerTest.java | 2 +- .../documentation/balance/room/RoomDocumentationTest.java | 2 +- .../test/java/ddangkong/domain/balance/room/RoomTest.java | 2 +- .../ddangkong/service/balance/room/RoomServiceTest.java | 2 +- backend/src/test/resources/init-test.sql | 6 +++--- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/Room.java b/backend/src/main/java/ddangkong/domain/balance/room/Room.java index f2d47953..90c4bf9d 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/Room.java @@ -18,7 +18,7 @@ public class Room { private static final int DEFAULT_TOTAL_ROUND = 5; - private static final int DEFAULT_TIME_LIMIT_MSEC = 10_000; + private static final int DEFAULT_TIME_LIMIT_MSEC = 30_000; private static final int START_ROUND = 1; @Id diff --git a/backend/src/main/resources/sql/data-dev.sql b/backend/src/main/resources/sql/data-dev.sql index 72d462bb..c11a759a 100644 --- a/backend/src/main/resources/sql/data-dev.sql +++ b/backend/src/main/resources/sql/data-dev.sql @@ -20,7 +20,7 @@ VALUES ('민초', 1), INSERT INTO room(total_round, current_round, time_limit, status) -VALUES (5, 1, 10000, 'READY'); +VALUES (5, 1, 30000, 'READY'); INSERT INTO room_content(room_id, balance_content_id, round, created_at) diff --git a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java index 860e6f9c..3dd04d50 100644 --- a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java @@ -35,7 +35,7 @@ class 밸런스_게임_방_정보_조회 { assertAll( () -> Assertions.assertThat(actual.members()).hasSize(4), () -> Assertions.assertThat(actual.isGameStart()).isTrue(), - () -> Assertions.assertThat(actual.roomSetting().timeLimit()).isEqualTo(10000), + () -> Assertions.assertThat(actual.roomSetting().timeLimit()).isEqualTo(30000), () -> Assertions.assertThat(actual.roomSetting().totalRound()).isEqualTo(5) ); } diff --git a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java index 9851fe7c..012f3e2d 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java @@ -123,7 +123,7 @@ class 방_정보_조회 { void 방_정보를_조회한다() throws Exception { //given int totalRound = 5; - int timeLimit = 10000; + int timeLimit = 30000; RoomInfoResponse response = new RoomInfoResponse( false, new RoomSettingResponse(totalRound, timeLimit), diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java index 0e2de294..2cde8032 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java @@ -32,7 +32,7 @@ class 다음_라운드로_이동 { // given int totalRound = 5; int currentRound = 5; - int timeLimit = 10000; + int timeLimit = 30000; Room room = new Room(totalRound, currentRound, timeLimit, RoomStatus.PROGRESS); // when & then diff --git a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java index 01671c4e..374e1852 100644 --- a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java @@ -38,7 +38,7 @@ class 게임_방_정보_조회 { assertAll( () -> Assertions.assertThat(actual.members()).hasSize(3), () -> Assertions.assertThat(actual.isGameStart()).isFalse(), - () -> Assertions.assertThat(actual.roomSetting().timeLimit()).isEqualTo(10000), + () -> Assertions.assertThat(actual.roomSetting().timeLimit()).isEqualTo(30000), () -> Assertions.assertThat(actual.roomSetting().totalRound()).isEqualTo(5) ); } diff --git a/backend/src/test/resources/init-test.sql b/backend/src/test/resources/init-test.sql index 26992130..f874c45a 100644 --- a/backend/src/test/resources/init-test.sql +++ b/backend/src/test/resources/init-test.sql @@ -1,7 +1,7 @@ INSERT INTO room (total_round, current_round, time_limit, status) -VALUES (5, 2, 10000, 'PROGRESS'), - (5, 1, 10000, 'PROGRESS'), - (5, 1, 10000, 'PROGRESS'); +VALUES (5, 2, 30000, 'PROGRESS'), + (5, 1, 30000, 'PROGRESS'), + (5, 1, 30000, 'PROGRESS'); INSERT INTO member (nickname, room_id, is_master) VALUES ('mohamedeu al katan', 1, true), From 66ea24fb2e3053b9e00b4486ec47edc4103ca4be Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 1 Aug 2024 13:39:30 +0900 Subject: [PATCH 0391/1013] =?UTF-8?q?test:=20renderHook=EC=9D=84=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20wrapper=EC=99=80=20RTL=20render=EB=A5=BC?= =?UTF-8?q?=20=EC=9C=84=ED=95=9C=20customRender=20=EA=B5=AC=ED=98=84=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{mocks/wrapper.tsx => utils/test-utils.tsx} | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) rename frontend/src/{mocks/wrapper.tsx => utils/test-utils.tsx} (60%) diff --git a/frontend/src/mocks/wrapper.tsx b/frontend/src/utils/test-utils.tsx similarity index 60% rename from frontend/src/mocks/wrapper.tsx rename to frontend/src/utils/test-utils.tsx index 62a3f0c3..a4e89750 100644 --- a/frontend/src/mocks/wrapper.tsx +++ b/frontend/src/utils/test-utils.tsx @@ -1,6 +1,9 @@ import { Global, ThemeProvider } from '@emotion/react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +// eslint-disable-next-line import/named +import { render, RenderOptions } from '@testing-library/react'; import { PropsWithChildren } from 'react'; +import { MemoryRouter } from 'react-router-dom'; import { RecoilRoot } from 'recoil'; import GlobalStyle from '@/styles/GlobalStyle'; @@ -19,12 +22,17 @@ const wrapper = ({ children }: PropsWithChildren) => { - - {children} + + + {children} + ); }; -export default wrapper; +const customRender = (ui: React.ReactNode, options?: RenderOptions) => + render(ui, { wrapper, ...options }); + +export { wrapper, customRender }; From 2c8cda6a4f38d646d11d2aa09b81fd6e64eb0cd8 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 1 Aug 2024 13:40:32 +0900 Subject: [PATCH 0392/1013] =?UTF-8?q?chore:=20jest=20test-utils=20?= =?UTF-8?q?=EA=B2=BD=EB=A1=9C=20=EC=84=A4=EC=A0=95=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/jest.config.json | 4 +++- frontend/tsconfig.json | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/frontend/jest.config.json b/frontend/jest.config.json index d06f8783..251d373a 100644 --- a/frontend/jest.config.json +++ b/frontend/jest.config.json @@ -3,8 +3,10 @@ "testEnvironmentOptions": { "customExportConditions": [""] }, + "moduleFileExtensions": ["js", "ts", "tsx"], "moduleNameMapper": { - "^@/(.*)$": "/src/$1" + "^@/(.*)$": "/src/$1", + "test-utils": "/src/utils/test-utils" }, "setupFiles": ["./jest.polyfills.js"], "setupFilesAfterEnv": ["/jest.setup.ts"] diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index 761405ef..7f35b567 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -15,9 +15,10 @@ "baseUrl": ".", // 모듈 해석 기본 경로 "paths": { // 경로 별칭 설정 - "@/*": ["src/*"] + "@/*": ["src/*"], + "test-utils": ["./src/utils/test-utils"] } }, - "include": ["src"], + "include": ["src", "jest.setup.ts"], "exclude": ["node_modules"] } From fcb6ebfa1845fc1363b385deb95041fa1848a840 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 1 Aug 2024 13:41:22 +0900 Subject: [PATCH 0393/1013] =?UTF-8?q?test:=20RoundVoteContainer=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=9E=91=EC=84=B1=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RoundVoteContainer.test.tsx | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 frontend/src/components/RoundVoteContainer/RoundVoteContainer.test.tsx diff --git a/frontend/src/components/RoundVoteContainer/RoundVoteContainer.test.tsx b/frontend/src/components/RoundVoteContainer/RoundVoteContainer.test.tsx new file mode 100644 index 00000000..cd96bb2a --- /dev/null +++ b/frontend/src/components/RoundVoteContainer/RoundVoteContainer.test.tsx @@ -0,0 +1,34 @@ +import { screen, waitFor } from '@testing-library/react'; +import { customRender } from 'test-utils'; + +import RoundVoteContainer from './RoundVoteContainer'; + +describe('RoundVoteContainer 컴포넌트 테스트', () => { + it('그룹탭과 전체탭이 존재한다.', () => { + customRender(); + + expect(screen.getByText('그룹')).toBeInTheDocument(); + expect(screen.getByText('전체')).toBeInTheDocument(); + }); + it('라운드 결과로 질문과 선택한 인원을 보여준다.', async () => { + customRender(); + + await waitFor(() => { + expect(screen.getByText('100억 빚 송강')).toBeInTheDocument(); + expect(screen.getByText('100억 부자 송강호')).toBeInTheDocument(); + expect(screen.getByText('7명')).toBeInTheDocument(); + expect(screen.getByText('3명')).toBeInTheDocument(); + }); + }); + it('라운드 결과 그룹원들이 선택한 퍼센트를 카운팅 애니메이션으로 보여준다.', async () => { + customRender(); + + await waitFor( + () => { + expect(screen.getByText('73%')).toBeInTheDocument(); + expect(screen.getByText('27%')).toBeInTheDocument(); + }, + { timeout: 3000 }, + ); + }); +}); From 19d9c5fa72fdf20214fb924e8f6869f90d94ac91 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 1 Aug 2024 13:41:58 +0900 Subject: [PATCH 0394/1013] =?UTF-8?q?style:=20=EA=B0=80=EB=8F=85=EC=84=B1?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EC=A4=84=EB=B0=94=EA=BF=88=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/RoundResultTab/RoundResultTab.tsx | 1 + .../RoundVoteContainer.test.tsx | 16 ---------------- .../TabContentContainer/TabContentContainer.tsx | 1 + 3 files changed, 2 insertions(+), 16 deletions(-) diff --git a/frontend/src/components/RoundResultTab/RoundResultTab.tsx b/frontend/src/components/RoundResultTab/RoundResultTab.tsx index 2a4823a0..2bac14a1 100644 --- a/frontend/src/components/RoundResultTab/RoundResultTab.tsx +++ b/frontend/src/components/RoundResultTab/RoundResultTab.tsx @@ -20,4 +20,5 @@ const RoundResultTab = ({ tab, activeTab, handleClickTab }: RoundResultTabProps) ); }; + export default RoundResultTab; diff --git a/frontend/src/components/RoundVoteContainer/RoundVoteContainer.test.tsx b/frontend/src/components/RoundVoteContainer/RoundVoteContainer.test.tsx index cd96bb2a..3dac3e23 100644 --- a/frontend/src/components/RoundVoteContainer/RoundVoteContainer.test.tsx +++ b/frontend/src/components/RoundVoteContainer/RoundVoteContainer.test.tsx @@ -4,22 +4,6 @@ import { customRender } from 'test-utils'; import RoundVoteContainer from './RoundVoteContainer'; describe('RoundVoteContainer 컴포넌트 테스트', () => { - it('그룹탭과 전체탭이 존재한다.', () => { - customRender(); - - expect(screen.getByText('그룹')).toBeInTheDocument(); - expect(screen.getByText('전체')).toBeInTheDocument(); - }); - it('라운드 결과로 질문과 선택한 인원을 보여준다.', async () => { - customRender(); - - await waitFor(() => { - expect(screen.getByText('100억 빚 송강')).toBeInTheDocument(); - expect(screen.getByText('100억 부자 송강호')).toBeInTheDocument(); - expect(screen.getByText('7명')).toBeInTheDocument(); - expect(screen.getByText('3명')).toBeInTheDocument(); - }); - }); it('라운드 결과 그룹원들이 선택한 퍼센트를 카운팅 애니메이션으로 보여준다.', async () => { customRender(); diff --git a/frontend/src/components/TabContentContainer/TabContentContainer.tsx b/frontend/src/components/TabContentContainer/TabContentContainer.tsx index 4184b1f3..b658983e 100644 --- a/frontend/src/components/TabContentContainer/TabContentContainer.tsx +++ b/frontend/src/components/TabContentContainer/TabContentContainer.tsx @@ -35,6 +35,7 @@ const TabContentContainer = ({ const goToVoteStatus = () => { navigate('/round/result/status'); }; + return (
    다른 사람들은 이렇게 생각했어요 🥜
    From fbfc732d217031b02ac9abc107e71d7e2788eaf6 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 1 Aug 2024 15:26:46 +0900 Subject: [PATCH 0395/1013] =?UTF-8?q?test:=20=EC=A0=84=EC=B2=B4=20?= =?UTF-8?q?=ED=83=AD=EC=9D=84=20=ED=81=B4=EB=A6=AD=ED=95=98=EB=A9=B4=20?= =?UTF-8?q?=EC=A0=84=EC=B2=B4=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=ED=86=B5?= =?UTF-8?q?=EA=B3=84=EB=A5=BC=20=ED=8D=BC=EC=84=BC=ED=8A=B8=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=B4=EC=97=AC=EC=A3=BC=EB=8A=94=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RoundVoteContainer.test.tsx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/frontend/src/components/RoundVoteContainer/RoundVoteContainer.test.tsx b/frontend/src/components/RoundVoteContainer/RoundVoteContainer.test.tsx index 3dac3e23..24d953b7 100644 --- a/frontend/src/components/RoundVoteContainer/RoundVoteContainer.test.tsx +++ b/frontend/src/components/RoundVoteContainer/RoundVoteContainer.test.tsx @@ -1,4 +1,5 @@ import { screen, waitFor } from '@testing-library/react'; +import { userEvent } from '@testing-library/user-event'; import { customRender } from 'test-utils'; import RoundVoteContainer from './RoundVoteContainer'; @@ -15,4 +16,20 @@ describe('RoundVoteContainer 컴포넌트 테스트', () => { { timeout: 3000 }, ); }); + it('기본 탭인 그룹 탭에서, 전체 탭을 클릭하면 전체 사용자 통계를 퍼센트로 보여준다.', async () => { + const user = userEvent.setup(); + customRender(); + + const button = await screen.findByRole('button', { name: '전체' }); + + await user.click(button); + + await waitFor( + () => { + expect(screen.getByText('16%')).toBeInTheDocument(); + expect(screen.getByText('84%')).toBeInTheDocument(); + }, + { timeout: 3000 }, + ); + }); }); From 6e91a5b7a2cb34711db132b6002c7be6b546939b Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Thu, 1 Aug 2024 15:29:53 +0900 Subject: [PATCH 0396/1013] =?UTF-8?q?feat:=20=EC=A0=84=EC=B2=B4=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B4=EB=93=9C=20=EC=A2=85=EB=A3=8C=20=EC=97=AC?= =?UTF-8?q?=EB=B6=80=20=ED=99=95=EC=9D=B8=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20#93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ddangkong/domain/balance/room/Room.java | 3 +-- .../domain/balance/room/RoomStatus.java | 4 ++++ .../ddangkong/domain/balance/room/RoomTest.java | 17 ++++++++++++----- .../service/balance/room/RoomServiceTest.java | 6 ++++-- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/Room.java b/backend/src/main/java/ddangkong/domain/balance/room/Room.java index 761b237c..b4d2804c 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/Room.java @@ -80,7 +80,6 @@ public boolean isMyRoundFinished(int myRound) { } public boolean isAllRoundFinished() { - // TODO: room의 status가 종료인지 여부 리턴 - return currentRound == totalRound; + return status.isGameFinish(); } } diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomStatus.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomStatus.java index 4397dd57..ed15d424 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomStatus.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomStatus.java @@ -9,4 +9,8 @@ public enum RoomStatus { public boolean isGameProgress() { return this == PROGRESS; } + + public boolean isGameFinish() { + return this == FINISH; + } } diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java index 735cd69d..2ee2a6e8 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java @@ -6,6 +6,8 @@ import ddangkong.exception.BadRequestException; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; class RoomTest { @@ -103,23 +105,28 @@ class 라운드_종료 { } @Test - void 전체_라운드가_종료되었으면_true를_반환한다() { // TODO + void 전체_라운드가_종료되었으면_true를_반환한다() { // given + Room room = new Room(FIXED_TOTAL_ROUND, 5, FIXED_TIME_LIMIT, RoomStatus.FINISH); // when + boolean actual = room.isAllRoundFinished(); // then - + assertThat(actual).isTrue(); } - @Test - void 전체_라운드가_종료되지_않았으면_false를_반환한다() { // TODO + @ParameterizedTest + @EnumSource(value = RoomStatus.class, names = {"READY", "PROGRESS"}) + void 전체_라운드가_종료되지_않았으면_false를_반환한다(RoomStatus status) { // given + Room room = new Room(FIXED_TOTAL_ROUND, 5, FIXED_TIME_LIMIT, status); // when + boolean actual = room.isAllRoundFinished(); // then - + assertThat(actual).isFalse(); } } } diff --git a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java index 857b6cb0..6683f0b4 100644 --- a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java @@ -160,10 +160,12 @@ class 나의_라운드_종료_여부 { } @Test - void 모든_라운드가_종료됐으면_나의_라운드도_종료된다() { // TODO + void 모든_라운드가_종료됐으면_나의_라운드도_종료된다() { // given int currentRound = 5; - Room room = roomRepository.save(new Room(FIXED_TOTAL_ROUND, currentRound, FIXED_TIME_LIMIT, FIXED_STATUS)); + Room room = roomRepository.save( + new Room(FIXED_TOTAL_ROUND, currentRound, FIXED_TIME_LIMIT, RoomStatus.FINISH) + ); // when RoundFinishedResponse roundFinishedResponse = roomService.getMyRoundFinished(room.getId(), 5); From a17318b7d104395cdb6dfffd067929abfaa0f34e Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Thu, 1 Aug 2024 15:30:11 +0900 Subject: [PATCH 0397/1013] =?UTF-8?q?refactor:=20=EB=94=94=EB=A0=89?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=20=EA=B2=BD=EB=A1=9C=20=EC=B9=B4=EB=A9=9C=20?= =?UTF-8?q?=EC=BC=80=EC=9D=B4=EC=8A=A4=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20#93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/docs/asciidoc/room.adoc | 12 ++++++------ .../balance/room/RoomDocumentationTest.java | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/backend/src/docs/asciidoc/room.adoc b/backend/src/docs/asciidoc/room.adoc index 7a7dc62a..2ad81007 100644 --- a/backend/src/docs/asciidoc/room.adoc +++ b/backend/src/docs/asciidoc/room.adoc @@ -90,20 +90,20 @@ include::{snippets}/room/next/response-fields.adoc[] ==== curl -include::{snippets}/room/round-finished/curl-request.adoc[] +include::{snippets}/room/roundFinished/curl-request.adoc[] ==== request -include::{snippets}/room/round-finished/http-request.adoc[] +include::{snippets}/room/roundFinished/http-request.adoc[] -include::{snippets}/room/round-finished/path-parameters.adoc[] +include::{snippets}/room/roundFinished/path-parameters.adoc[] -include::{snippets}/room/round-finished/query-parameters.adoc[] +include::{snippets}/room/roundFinished/query-parameters.adoc[] ==== response -include::{snippets}/room/round-finished/http-response.adoc[] +include::{snippets}/room/roundFinished/http-response.adoc[] response fields -include::{snippets}/room/round-finished/response-fields.adoc[] +include::{snippets}/room/roundFinished/response-fields.adoc[] diff --git a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java index a03a2468..6f04d82f 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java @@ -7,10 +7,10 @@ import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; -import static org.springframework.restdocs.payload.JsonFieldType.*; import static org.springframework.restdocs.payload.JsonFieldType.ARRAY; import static org.springframework.restdocs.payload.JsonFieldType.BOOLEAN; import static org.springframework.restdocs.payload.JsonFieldType.NUMBER; +import static org.springframework.restdocs.payload.JsonFieldType.OBJECT; import static org.springframework.restdocs.payload.JsonFieldType.STRING; import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; @@ -218,7 +218,7 @@ class 나의_라운드_종료_여부 { .param("myRound", "1") ) .andExpect(status().isOk()) - .andDo(document("room/round-finished", + .andDo(document("room/roundFinished", pathParameters( parameterWithName("roomId").description("방 ID") ), From 3bb49ef6353fb30b937f33ed9d675852f723eaff Mon Sep 17 00:00:00 2001 From: useon Date: Thu, 1 Aug 2024 15:39:06 +0900 Subject: [PATCH 0398/1013] =?UTF-8?q?refactor:=20=EB=AA=A8=EB=8B=AC?= =?UTF-8?q?=EC=9D=98=20=EC=A0=9C=EB=AA=A9=EC=9D=84=20=EC=8B=9C=EB=A7=A8?= =?UTF-8?q?=ED=8B=B1=20=ED=83=9C=EA=B7=B8=EB=A1=9C=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?#60?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/common/Modal/Modal.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/common/Modal/Modal.tsx b/frontend/src/components/common/Modal/Modal.tsx index d9786eaf..eaa491cc 100644 --- a/frontend/src/components/common/Modal/Modal.tsx +++ b/frontend/src/components/common/Modal/Modal.tsx @@ -63,13 +63,13 @@ const ModalHeader = ({ children, ...restProps }: ModalHeaderProps) => { ); }; -interface ModalTitleProps extends React.PropsWithChildren> {} +interface ModalTitleProps extends React.PropsWithChildren> {} const ModalTitle = ({ children, ...restProps }: ModalTitleProps) => { return ( - +

    {children} - +

    ); }; From 8320502b95a732452d9117a4bc3424c574a1e454 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Thu, 1 Aug 2024 15:38:07 +0900 Subject: [PATCH 0399/1013] =?UTF-8?q?refactor:=20validate=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EB=B6=84=EB=A6=AC=20=EB=B0=8F=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?#93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ddangkong/domain/balance/room/Room.java | 22 +++++++++++++------ .../domain/balance/room/RoomTest.java | 4 ++-- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/Room.java b/backend/src/main/java/ddangkong/domain/balance/room/Room.java index b4d2804c..8013c6ea 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/Room.java @@ -66,17 +66,25 @@ public boolean isGameProgress() { } public boolean isMyRoundFinished(int myRound) { - if (myRound < START_ROUND) { - throw new BadRequestException("나의 라운드는 %d보다 크거나 같아야 합니다. myRound : %d" - .formatted(START_ROUND, myRound) + validateGreaterThanOrEqualToStartRound(myRound); + validateLessThanOrEqualToCurrentRound(myRound); + return currentRound != myRound; + } + + private void validateGreaterThanOrEqualToStartRound(int round) { + if (round < START_ROUND) { + throw new BadRequestException("startRound보다 크거나 같아야 합니다. startRound : %d, round : %d" + .formatted(START_ROUND, round) ); } - if (currentRound < myRound) { - throw new BadRequestException("방의 currentRound보다 작거나 같아야 합니다. currentRound : %d, myRound : %d" - .formatted(currentRound, myRound) + } + + private void validateLessThanOrEqualToCurrentRound(int round) { + if (currentRound < round) { + throw new BadRequestException("currentRound보다 작거나 같아야 합니다. currentRound : %d, round : %d" + .formatted(currentRound, round) ); } - return currentRound != myRound; } public boolean isAllRoundFinished() { diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java index 2ee2a6e8..ccf39e8a 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java @@ -88,7 +88,7 @@ class 라운드_종료 { // when & then assertThatThrownBy(() -> room.isMyRoundFinished(invalidMyRound)) .isExactlyInstanceOf(BadRequestException.class) - .hasMessageContaining("나의 라운드는 1보다 크거나 같아야 합니다. myRound : 0"); + .hasMessageContaining("startRound보다 크거나 같아야 합니다. startRound : 1, round : 0"); } @Test @@ -101,7 +101,7 @@ class 라운드_종료 { // when & then assertThatThrownBy(() -> room.isMyRoundFinished(invalidMyRound)) .isExactlyInstanceOf(BadRequestException.class) - .hasMessageContaining("방의 currentRound보다 작거나 같아야 합니다. currentRound : 1, myRound : 2"); + .hasMessageContaining("currentRound보다 작거나 같아야 합니다. currentRound : 1, round : 2"); } @Test From 40dbafcde81acf02e12c59b71bad70d45360364d Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 1 Aug 2024 15:40:53 +0900 Subject: [PATCH 0400/1013] =?UTF-8?q?chore:=20CD=20=EA=B3=BC=EC=A0=95?= =?UTF-8?q?=EC=97=90=20=EA=B8=B0=EC=A1=B4=20=EB=8F=84=EC=BB=A4=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EC=82=AD=EC=A0=9C=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=BD=ED=8A=B8=20=EC=B6=94=EA=B0=80=20#100?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 9e392deb..c3d32351 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -73,11 +73,20 @@ jobs: run: | CONTAINER_ID=$(sudo docker ps -aqf name=$CONTAINER_NAME) if [ -n ${CONTAINER_ID} ]; then - sudo docker rm -f ${CONTAINER_ID} + sudo docker rm -f ${CONTAINER_ID} else echo "No previous container found with name. Skipping removal." fi + - name: Remove previous Docker image + run: | + IMAGE_ID=$(sudo docker images --filter=reference=ddangkong/ddangkong-api-dev --format "{{.ID}}") + if [ -n ${IMAGE_ID} ]; then + sudo docker rmi ${IMAGE_ID} + else + echo "No previous image found with repository name. Skipping removal." + fi + - name: Run new Docker container run: | sudo nohup docker run -p 80:8080 --name $CONTAINER_NAME \ From e1b53026f41f204f85b3cf6e1a726ce6204e9bf3 Mon Sep 17 00:00:00 2001 From: useon Date: Thu, 1 Aug 2024 15:43:12 +0900 Subject: [PATCH 0401/1013] =?UTF-8?q?refactor:=20=EC=8A=A4=ED=83=80?= =?UTF-8?q?=EC=9D=BC=20prop=EC=97=90=EB=8A=94=20=EC=A1=B4=EC=9E=AC?= =?UTF-8?q?=ED=95=98=EC=A7=80=EB=A7=8C=20=EB=A1=9C=EC=A7=81=EC=97=90=20?= =?UTF-8?q?=EB=B9=A0=EC=A7=84=20prop=20=EC=B6=94=EA=B0=80=20#60?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/common/Modal/Modal.tsx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/common/Modal/Modal.tsx b/frontend/src/components/common/Modal/Modal.tsx index eaa491cc..629fce92 100644 --- a/frontend/src/components/common/Modal/Modal.tsx +++ b/frontend/src/components/common/Modal/Modal.tsx @@ -63,9 +63,12 @@ const ModalHeader = ({ children, ...restProps }: ModalHeaderProps) => { ); }; -interface ModalTitleProps extends React.PropsWithChildren> {} +interface ModalTitleProps extends React.PropsWithChildren> { + fontSize?: string; + fontWeight?: string; +} -const ModalTitle = ({ children, ...restProps }: ModalTitleProps) => { +const ModalTitle = ({ children, fontSize, fontWeight, ...restProps }: ModalTitleProps) => { return (

    {children} @@ -123,9 +126,11 @@ const ModalTextButton = ({ ); }; -interface ModalContentProps extends React.PropsWithChildren> {} +interface ModalContentProps extends React.PropsWithChildren> { + fontSize?: string; +} -const ModalContent = ({ children, ...restProps }: ModalContentProps) => { +const ModalContent = ({ children, fontSize, ...restProps }: ModalContentProps) => { return (
    {children} From 62be54f9056313a8c4ef56126dc02bd2ec2219fe Mon Sep 17 00:00:00 2001 From: novice0840 Date: Thu, 1 Aug 2024 15:54:08 +0900 Subject: [PATCH 0402/1013] =?UTF-8?q?feat:=20=EB=8B=89=EB=84=A4=EC=9E=84?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=ED=9B=84=20=EB=8C=80=EA=B8=B0=EB=B0=A9?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99=20#92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/room.ts | 20 ++++++++-- frontend/src/pages/MainPage/MainPage.tsx | 12 +++++- .../src/pages/NicknamePage/NicknamePage.tsx | 37 ++++++++++++++++--- frontend/src/pages/ReadyPage/ReadyPage.tsx | 2 +- frontend/src/recoil/atom.ts | 10 +++++ frontend/src/types/room.ts | 14 +++++++ 6 files changed, 82 insertions(+), 13 deletions(-) create mode 100644 frontend/src/recoil/atom.ts create mode 100644 frontend/src/types/room.ts diff --git a/frontend/src/apis/room.ts b/frontend/src/apis/room.ts index a797fa64..24426ec2 100644 --- a/frontend/src/apis/room.ts +++ b/frontend/src/apis/room.ts @@ -1,10 +1,10 @@ import fetcher from './fetcher'; -import { nickname } from '@/components/GameResultItem/GameResultItem.styled'; import { API_URL } from '@/constants/url'; +import { RoomAndMember, RoomMembers } from '@/types/room'; // 방 만들기 -export const makeRoom = async (nickname: string) => { +export const makeRoom = async (nickname: string): Promise => { const res = await fetcher.post({ url: API_URL.room, headers: { @@ -15,13 +15,17 @@ export const makeRoom = async (nickname: string) => { }, }); + if (!res.ok) { + throw new Error('방 생성에 실패하였습니다'); + } + const data = await res.json(); return data; }; // 방 참여하기 -export const enterRoom = async (roomId: number, nickname: string) => { +export const enterRoom = async (roomId: number, nickname: string): Promise => { const res = await fetcher.post({ url: API_URL.roomMembers(roomId), headers: { @@ -32,17 +36,25 @@ export const enterRoom = async (roomId: number, nickname: string) => { }, }); + if (!res.ok) { + throw new Error('방 참여에 실패하였습니다'); + } + const data = await res.json(); return data; }; // 방 전체 멤버 조회 -export const getMembers = async (roomId: number) => { +export const getMembers = async (roomId: number): Promise => { const res = await fetcher.get({ url: API_URL.roomMembers(roomId), }); + if (!res.ok) { + throw new Error('방 멤버 가져오기에 실패하였습니다'); + } + const data = await res.json(); return data; diff --git a/frontend/src/pages/MainPage/MainPage.tsx b/frontend/src/pages/MainPage/MainPage.tsx index 1c47f446..ce6578ad 100644 --- a/frontend/src/pages/MainPage/MainPage.tsx +++ b/frontend/src/pages/MainPage/MainPage.tsx @@ -1,14 +1,22 @@ import { useNavigate } from 'react-router-dom'; +import { useSetRecoilState } from 'recoil'; import { mainPageLayout, logoWrapper, title, intro } from './MainPage.styled'; import Button from '@/components/common/Button/Button'; +import { memberInfoState } from '@/recoil/atom'; const MainPage = () => { const navigate = useNavigate(); + const setMemberInfo = useSetRecoilState(memberInfoState); const goToNicknamePage = () => { - navigate('/nickname', { state: { isMaster: true } }); + navigate('/nickname'); + }; + + const handleClick = () => { + goToNicknamePage(); + setMemberInfo((memberInfo) => ({ ...memberInfo, isMaster: true })); }; return ( @@ -16,7 +24,7 @@ const MainPage = () => {
    LO to the GO

    땅콩

    어색한 분위기를 주도해봐요

    - +

    ); }; diff --git a/frontend/src/pages/NicknamePage/NicknamePage.tsx b/frontend/src/pages/NicknamePage/NicknamePage.tsx index e109c201..bc47a83d 100644 --- a/frontend/src/pages/NicknamePage/NicknamePage.tsx +++ b/frontend/src/pages/NicknamePage/NicknamePage.tsx @@ -1,25 +1,50 @@ +import { useMutation } from '@tanstack/react-query'; import { useRef } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; +import { useRecoilState } from 'recoil'; import { profile, nickname, nicknameInputWrapper, nicknameInput } from './NicknamePage.styled'; +import { enterRoom, makeRoom } from '@/apis/room'; import Button from '@/components/common/Button/Button'; import Content from '@/components/layout/Content/Content'; +import { memberInfoState } from '@/recoil/atom'; +import { RoomAndMember } from '@/types/room'; import { createRandomNickname } from '@/utils/nickname'; const NicknamePage = () => { const randomNickname = createRandomNickname(); const nicknameInputRef = useRef(null); const navigate = useNavigate(); + const [{ isMaster }, setMemberInfo] = useRecoilState(memberInfoState); + const { search } = useLocation(); + const roomId = Number(new URLSearchParams(search).get('roomId')); + const nickname = nicknameInputRef.current?.value || randomNickname; - const goToReadyPage = () => { - navigate('/ready', { state: { isMaster: true } }); - }; + const makeRoomMutation = useMutation({ + mutationFn: makeRoom, + onSuccess: (data) => { + navigate(`/ready?roomId=${data.roomId}`); + }, + onError: (error: Error) => {}, + }); - const { state } = useLocation(); + const enterRoomMutation = useMutation( + { + mutationFn: ({ nickname, roomId }) => enterRoom(roomId, nickname), + onSuccess: (data) => { + navigate(`/ready?roomId=${data.roomId}`); + }, + onError: (error: Error) => {}, + }, + ); const handleClick = () => { - alert(`${state?.isMaster}, ${nicknameInputRef.current?.value || randomNickname}`); + if (isMaster) { + makeRoomMutation.mutate(nickname); + } else { + enterRoomMutation.mutate({ nickname, roomId }); + } }; return ( @@ -34,7 +59,7 @@ const NicknamePage = () => { ref={nicknameInputRef} /> - + ); }; diff --git a/frontend/src/pages/ReadyPage/ReadyPage.tsx b/frontend/src/pages/ReadyPage/ReadyPage.tsx index 6505e7b5..0bea1ab2 100644 --- a/frontend/src/pages/ReadyPage/ReadyPage.tsx +++ b/frontend/src/pages/ReadyPage/ReadyPage.tsx @@ -13,7 +13,7 @@ const ReadyPage = () => {
    -
    ); }; diff --git a/frontend/src/recoil/atom.ts b/frontend/src/recoil/atom.ts new file mode 100644 index 00000000..3984ea6b --- /dev/null +++ b/frontend/src/recoil/atom.ts @@ -0,0 +1,10 @@ +import { atom } from 'recoil'; + +export const memberInfoState = atom({ + key: 'memberInfo', + default: { + memberId: null, + nickname: null, + isMaster: false, + }, +}); diff --git a/frontend/src/types/room.ts b/frontend/src/types/room.ts new file mode 100644 index 00000000..bcfe2668 --- /dev/null +++ b/frontend/src/types/room.ts @@ -0,0 +1,14 @@ +interface Member { + memberId: number; + nickname: string; + isMaster: boolean; +} + +export interface RoomAndMember { + roomId: number; + member: Member; +} + +export interface RoomMembers { + members: Member[]; +} From 13e0a328bbc350a09a79fc7c3d91486285ec101c Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:00:48 +0900 Subject: [PATCH 0403/1013] =?UTF-8?q?chore:=20CI/CD=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=BD=ED=8A=B8=20=ED=83=80=EC=9E=84=EC=95=84=EC=9B=83=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20#100?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 ++ .github/workflows/be-ci-dev.yml | 1 + 2 files changed, 3 insertions(+) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index c3d32351..1918b2b4 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -10,6 +10,7 @@ on: jobs: build: + timeout-minutes: 3 runs-on: ubuntu-latest env: DOCKER_REPOSITORY_NAME: ddangkong/ddangkong-api-dev @@ -54,6 +55,7 @@ jobs: deploy: needs: build + timeout-minutes: 1 runs-on: [ self-hosted, linux, ARM64 ] # Self hosted runner 사용 env: DOCKER_REPOSITORY_NAME: ddangkong/ddangkong-api-dev diff --git a/.github/workflows/be-ci-dev.yml b/.github/workflows/be-ci-dev.yml index 136ca32e..70954614 100644 --- a/.github/workflows/be-ci-dev.yml +++ b/.github/workflows/be-ci-dev.yml @@ -10,6 +10,7 @@ on: jobs: build: + timeout-minutes: 4 runs-on: ubuntu-latest defaults: From 8868e5c9c3ff280b4b6f4af907f550e81a8c0290 Mon Sep 17 00:00:00 2001 From: useon Date: Thu, 1 Aug 2024 16:08:23 +0900 Subject: [PATCH 0404/1013] =?UTF-8?q?fix:=20=EC=98=B5=EC=85=98=20=EC=9D=B8?= =?UTF-8?q?=EC=9E=90=EA=B0=80=20=EC=9E=85=EB=A0=A5=EB=90=98=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EC=95=98=EC=9D=84=20=EB=95=8C=20=EA=B8=B0=EB=B3=B8=20?= =?UTF-8?q?=EC=8A=A4=ED=83=80=EC=9D=BC=EC=9D=B4=20=EC=A0=81=EC=9A=A9=20?= =?UTF-8?q?=EC=95=88=20=EB=90=98=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0=20#60?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/common/Modal/Modal.styled.ts | 43 ++++++++++--------- .../src/components/common/Modal/Modal.tsx | 4 +- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/frontend/src/components/common/Modal/Modal.styled.ts b/frontend/src/components/common/Modal/Modal.styled.ts index aa6677c0..dc339698 100644 --- a/frontend/src/components/common/Modal/Modal.styled.ts +++ b/frontend/src/components/common/Modal/Modal.styled.ts @@ -72,12 +72,12 @@ interface ModalTitleProps { fontWeight?: string; } -export const modalTitle = ({ fontSize, fontWeight }: ModalTitleProps) => css` - font-weight: ${fontWeight || 'bold'}; - font-size: ${fontSize || '2rem'}; +export const modalTitle = ({ fontSize = 'bold', fontWeight = '2rem' }: ModalTitleProps) => css` + font-weight: ${fontWeight}; + font-size: ${fontSize}; `; -export const modalIconButton = ({ imgSize }: { imgSize?: string }) => css` +export const modalIconButton = ({ imgSize = '1.6rem' }: { imgSize?: string }) => css` margin: 0 0 0 auto; padding: 0; border: none; @@ -87,7 +87,7 @@ export const modalIconButton = ({ imgSize }: { imgSize?: string }) => css` } img { - width: ${imgSize || '1.6rem'}; + width: ${imgSize}; } `; @@ -100,25 +100,25 @@ interface ModalTextButtonProps { } export const modalTextButton = ({ - buttonWidth, - buttonHeight, - fontSize, - backgroundColor, - fontColor, + buttonWidth = '100%', + buttonHeight = '100%', + fontSize = '1.6rem', + backgroundColor = Theme.color.peanut400, + fontColor = '#000000', }: ModalTextButtonProps) => css` display: flex; justify-content: center; align-items: center; - width: ${buttonWidth || '100%'}; - height: ${buttonHeight || '100%'}; + width: ${buttonWidth}; + height: ${buttonHeight}; padding: 1rem; border: none; - background-color: ${backgroundColor || Theme.color.peanut400}; + background-color: ${backgroundColor}; - color: ${fontColor || '#000000'}; + color: ${fontColor}; font-weight: bold; - font-size: ${fontSize || '1.6rem'}; + font-size: ${fontSize}; border-radius: 0; border-radius: 0.8rem; @@ -131,12 +131,12 @@ interface ModalContentProps { fontSize?: string; } -export const modalContentLayout = ({ fontSize }: ModalContentProps) => css` +export const modalContentLayout = ({ fontSize = '1.2rem' }: ModalContentProps) => css` * { box-sizing: border-box; } - font-size: ${fontSize || '1.2rem'}; + font-size: ${fontSize}; `; export const modalInputLayout = css` @@ -150,8 +150,11 @@ interface ModalFooterProps { buttonGap?: string; } -export const modalFooter = ({ buttonPosition, buttonGap }: ModalFooterProps) => css` +export const modalFooter = ({ + buttonPosition = 'center', + buttonGap = '1.2rem', +}: ModalFooterProps) => css` display: flex; - justify-content: ${buttonPosition || 'center'}; - gap: ${buttonGap || '1.2rem'}; + justify-content: ${buttonPosition}; + gap: ${buttonGap}; `; diff --git a/frontend/src/components/common/Modal/Modal.tsx b/frontend/src/components/common/Modal/Modal.tsx index 629fce92..6a52805b 100644 --- a/frontend/src/components/common/Modal/Modal.tsx +++ b/frontend/src/components/common/Modal/Modal.tsx @@ -68,9 +68,9 @@ interface ModalTitleProps extends React.PropsWithChildren { +const ModalTitle = ({ fontSize, fontWeight, children, ...restProps }: ModalTitleProps) => { return ( -

    +

    {children}

    ); From 6f2dd54e2d08edeb50f31813e3d55c4d4a32637f Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:10:57 +0900 Subject: [PATCH 0405/1013] =?UTF-8?q?fix:=20if=20else=EB=AC=B8=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EB=93=A4=EC=97=AC=EC=93=B0?= =?UTF-8?q?=EA=B8=B0=20=EC=88=98=EC=A0=95=20#100?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 1918b2b4..7d19ff37 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -75,18 +75,18 @@ jobs: run: | CONTAINER_ID=$(sudo docker ps -aqf name=$CONTAINER_NAME) if [ -n ${CONTAINER_ID} ]; then - sudo docker rm -f ${CONTAINER_ID} + sudo docker rm -f ${CONTAINER_ID} else - echo "No previous container found with name. Skipping removal." + echo "No previous container found with name. Skipping removal." fi - name: Remove previous Docker image run: | IMAGE_ID=$(sudo docker images --filter=reference=ddangkong/ddangkong-api-dev --format "{{.ID}}") if [ -n ${IMAGE_ID} ]; then - sudo docker rmi ${IMAGE_ID} + sudo docker rmi ${IMAGE_ID} else - echo "No previous image found with repository name. Skipping removal." + echo "No previous image found with repository name. Skipping removal." fi - name: Run new Docker container From 9444d37d3635f4aec16b7852a7efbc4dec66991d Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Thu, 1 Aug 2024 16:13:12 +0900 Subject: [PATCH 0406/1013] =?UTF-8?q?refactor:=20transactional=20=EC=95=A0?= =?UTF-8?q?=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=B6=94=EA=B0=80=20#93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/ddangkong/service/balance/room/RoomService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index f409bd1a..5a677e20 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -72,6 +72,7 @@ private RoomContent findCurrentRoomContent(Room room) { .orElseThrow(() -> new BadRequestException("해당 방의 현재 진행중인 질문이 존재하지 않습니다.")); } + @Transactional(readOnly = true) public RoundFinishedResponse getMyRoundFinished(Long roomId, int myRound) { Room room = roomRepository.getById(roomId); if (room.isAllRoundFinished()) { From 8b640a3280c0e01fa7a314379ecb3dcf21905166 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:17:11 +0900 Subject: [PATCH 0407/1013] =?UTF-8?q?fix:=20Docker=20image=20pull=20?= =?UTF-8?q?=EB=8F=99=EC=9E=91=20=EC=9C=84=EC=B9=98=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?#100?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 7d19ff37..d4d357e7 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -68,9 +68,6 @@ jobs: username: ${{ secrets.DOCKER_GMAIL }} password: ${{ secrets.DOCKER_TOKEN }} - - name: Pull docker image - run: sudo docker pull $DOCKER_REPOSITORY_NAME:latest - - name: Stop and Remove previous Docker container run: | CONTAINER_ID=$(sudo docker ps -aqf name=$CONTAINER_NAME) @@ -89,6 +86,9 @@ jobs: echo "No previous image found with repository name. Skipping removal." fi + - name: Pull docker image + run: sudo docker pull $DOCKER_REPOSITORY_NAME:latest + - name: Run new Docker container run: | sudo nohup docker run -p 80:8080 --name $CONTAINER_NAME \ From 6bc5606c6e9dc3055153a9dfd2bb94384d9e81c1 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:43:18 +0900 Subject: [PATCH 0408/1013] =?UTF-8?q?fix:=20=ED=99=98=EA=B2=BD=EB=B3=80?= =?UTF-8?q?=EC=88=98=EA=B0=80=20=EB=B9=84=EC=96=B4=EC=9E=88=EB=8A=94=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20if=EB=AC=B8=EC=97=90=EC=84=9C=20=EB=B0=9C?= =?UTF-8?q?=EC=83=9D=ED=95=98=EB=8A=94=20=EC=98=A4=EB=A5=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20#100?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index d4d357e7..40cfee34 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -71,7 +71,7 @@ jobs: - name: Stop and Remove previous Docker container run: | CONTAINER_ID=$(sudo docker ps -aqf name=$CONTAINER_NAME) - if [ -n ${CONTAINER_ID} ]; then + if [ -n "${CONTAINER_ID}" ]; then sudo docker rm -f ${CONTAINER_ID} else echo "No previous container found with name. Skipping removal." @@ -80,7 +80,7 @@ jobs: - name: Remove previous Docker image run: | IMAGE_ID=$(sudo docker images --filter=reference=ddangkong/ddangkong-api-dev --format "{{.ID}}") - if [ -n ${IMAGE_ID} ]; then + if [ -n "${IMAGE_ID}" ]; then sudo docker rmi ${IMAGE_ID} else echo "No previous image found with repository name. Skipping removal." From 5de51050d94af33189e0c35cc1fb8fa1b01693ae Mon Sep 17 00:00:00 2001 From: novice0840 Date: Thu, 1 Aug 2024 16:45:55 +0900 Subject: [PATCH 0409/1013] =?UTF-8?q?feat:=20=EB=8C=80=EA=B8=B0=EB=B0=A9?= =?UTF-8?q?=EC=97=90=EC=84=9C=201=EC=B4=88=EB=A7=88=EB=8B=A4=20=EB=B0=A9?= =?UTF-8?q?=20=EB=A9=A4=EB=B2=84=20=ED=98=B8=EC=B6=9C=20#92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/room.ts | 2 +- .../ReadyMembersContainer.tsx | 1 - frontend/src/constants/queryKeys.ts | 1 + frontend/src/pages/ReadyPage/ReadyPage.tsx | 22 ++++++++++++++++--- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/frontend/src/apis/room.ts b/frontend/src/apis/room.ts index 24426ec2..e386b34f 100644 --- a/frontend/src/apis/room.ts +++ b/frontend/src/apis/room.ts @@ -46,7 +46,7 @@ export const enterRoom = async (roomId: number, nickname: string): Promise => { +export const getRoomMembers = async (roomId: number): Promise => { const res = await fetcher.get({ url: API_URL.roomMembers(roomId), }); diff --git a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx index c22d1715..362768e0 100644 --- a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx +++ b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx @@ -6,7 +6,6 @@ import { profileBox, memberStatus, } from './ReadyMembersContainer.styled'; -import { nickname } from '../GameResultItem/GameResultItem.styled'; const example = { isGameStart: false, diff --git a/frontend/src/constants/queryKeys.ts b/frontend/src/constants/queryKeys.ts index d51c1709..19414d76 100644 --- a/frontend/src/constants/queryKeys.ts +++ b/frontend/src/constants/queryKeys.ts @@ -2,4 +2,5 @@ export const QUERY_KEYS = { balanceContent: 'balanceContent', gameResult: 'gameResult', roundVoteResult: 'roundVoteResult', + roomMembers: 'roomMembers', } as const; diff --git a/frontend/src/pages/ReadyPage/ReadyPage.tsx b/frontend/src/pages/ReadyPage/ReadyPage.tsx index 0bea1ab2..45bab533 100644 --- a/frontend/src/pages/ReadyPage/ReadyPage.tsx +++ b/frontend/src/pages/ReadyPage/ReadyPage.tsx @@ -1,19 +1,35 @@ -import React from 'react'; +import { useQuery } from '@tanstack/react-query'; +import { useLocation } from 'react-router-dom'; +import { useRecoilValue } from 'recoil'; import { readyPageLayout } from './ReadyPage.styled'; +import { getRoomMembers } from '@/apis/room'; import CategoryContainer from '@/components/CategoryContainer/CategoryContainer'; import Button from '@/components/common/Button/Button'; import ReadyMembersContainer from '@/components/ReadyMembersContainer/ReadyMembersContainer'; +import { QUERY_KEYS } from '@/constants/queryKeys'; +import { memberInfoState } from '@/recoil/atom'; const ReadyPage = () => { const handleClick = () => {}; + const memberInfo = useRecoilValue(memberInfoState); + const { search } = useLocation(); + const roomId = Number(new URLSearchParams(search).get('roomId')); + + const { data, isLoading, isError } = useQuery({ + queryKey: [QUERY_KEYS.roomMembers, roomId], + queryFn: ({ queryKey: [_, roomId] }) => getRoomMembers(roomId as number), + refetchInterval: 1000, + }); return (
    - -
    ); }; From 042b7e5fdc1095ba5c4017d35d76835abc92aff9 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 1 Aug 2024 17:12:24 +0900 Subject: [PATCH 0410/1013] =?UTF-8?q?feat:=20=EB=8B=A4=EC=9D=8C=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B4=EB=93=9C=EB=A1=9C=20=EB=84=98=EC=96=B4?= =?UTF-8?q?=EA=B0=80=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?#99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ddangkong/domain/balance/room/Room.java | 7 +++++ .../domain/balance/room/RoomStatus.java | 4 +++ .../domain/balance/room/RoomTest.java | 30 +++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/Room.java b/backend/src/main/java/ddangkong/domain/balance/room/Room.java index 90c4bf9d..73a6a14a 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/Room.java @@ -49,6 +49,13 @@ public Room(int totalRound, int currentRound, int timeLimit, RoomStatus status) this.status = status; } + public void startGame() { + if (status.isAlreadyStart()) { + throw new BadRequestException("이미 게임이 시작했습니다."); + } + status = RoomStatus.PROGRESS; + } + public void moveToNextRound() { if (canMoveToNextRound()) { currentRound++; diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomStatus.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomStatus.java index 4397dd57..c2126b71 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomStatus.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomStatus.java @@ -6,6 +6,10 @@ public enum RoomStatus { FINISH, ; + public boolean isAlreadyStart() { + return this != READY; + } + public boolean isGameProgress() { return this == PROGRESS; } diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java index 2cde8032..0118b3f6 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java @@ -6,9 +6,39 @@ import ddangkong.exception.BadRequestException; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; class RoomTest { + @Nested + class 게임_시작 { + + @Test + void 게임이_준비_상태일_떄_게임을_시작할_수_있다() { + // given + Room room = Room.createNewRoom(); + + // when + room.startGame(); + + // then + assertThat(room.isGameProgress()).isTrue(); + } + + @ParameterizedTest + @CsvSource({"PROGRESS", "FINISH"}) + void 게임이_이미_시작했다면_예외를_던진다(RoomStatus status) { + // given + Room room = new Room(5, 1, 30_000, status); + + // when & then + assertThatThrownBy(room::startGame) + .isInstanceOf(BadRequestException.class) + .hasMessage("이미 게임이 시작했습니다."); + } + } + @Nested class 다음_라운드로_이동 { From b0d8099e2fc876d174313f78a4248db397ef1bc7 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 1 Aug 2024 17:19:15 +0900 Subject: [PATCH 0411/1013] =?UTF-8?q?refactor:=20TabContentContainer=20?= =?UTF-8?q?=EB=82=B4=EB=B6=80=EB=A1=9C=20=EB=A1=9C=EC=A7=81=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RoundVoteContainer/RoundVoteContainer.tsx | 28 +--------- .../TabContentContainer.stories.tsx | 8 --- .../TabContentContainer.styled.ts | 4 +- .../TabContentContainer.tsx | 54 +++++++++++-------- 4 files changed, 35 insertions(+), 59 deletions(-) diff --git a/frontend/src/components/RoundVoteContainer/RoundVoteContainer.tsx b/frontend/src/components/RoundVoteContainer/RoundVoteContainer.tsx index 12129946..e5cd97a3 100644 --- a/frontend/src/components/RoundVoteContainer/RoundVoteContainer.tsx +++ b/frontend/src/components/RoundVoteContainer/RoundVoteContainer.tsx @@ -1,50 +1,24 @@ import { useState } from 'react'; -import { useTotalCountAnimation } from './RoundVoteContainer.hook'; import { tabLayout, tabWrapper } from './RoundVoteContainer.styled'; import RoundResultTab from '../RoundResultTab/RoundResultTab'; import TabContentContainer from '../TabContentContainer/TabContentContainer'; -import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; -import useRoundVoteResultQuery from '@/hooks/useRoundVoteResultQuery'; - const RoundVoteContainer = () => { const [activeTab, setActiveTab] = useState<'group' | 'total'>('group'); const isGroupTabActive = activeTab === 'group'; - const { balanceContent } = useBalanceContentQuery(); - const { groupRoundResult, totalResult } = useRoundVoteResultQuery({ - roomId: 1, - contentId: balanceContent?.contentId, - }); - - const { - animatedFirstPercent, - animatedSecondPercent, - animatedTotalFirstPercent, - animatedTotalSecondPercent, - } = useTotalCountAnimation(groupRoundResult, totalResult); - const handleClickTab = (clickedTab: 'group' | 'total') => { setActiveTab(clickedTab); }; - if (!groupRoundResult || !totalResult) return
    데이터가 없습니다
    ; - return (
    - +
    ); }; diff --git a/frontend/src/components/TabContentContainer/TabContentContainer.stories.tsx b/frontend/src/components/TabContentContainer/TabContentContainer.stories.tsx index 543209f6..70af96df 100644 --- a/frontend/src/components/TabContentContainer/TabContentContainer.stories.tsx +++ b/frontend/src/components/TabContentContainer/TabContentContainer.stories.tsx @@ -2,8 +2,6 @@ import type { Meta, StoryObj } from '@storybook/react'; import TabContentContainer from './TabContentContainer'; -import ROUND_VOTE_RESULT from '@/mocks/data/roundVoteResult.json'; - const meta = { title: 'TabContentContainer', component: TabContentContainer, @@ -16,9 +14,6 @@ type Story = StoryObj; export const 그룹_탭: Story = { args: { isGroupTabActive: true, - roundResult: ROUND_VOTE_RESULT.group, - animatedFirstPercent: ROUND_VOTE_RESULT.group.firstOption.percent, - animatedSecondPercent: ROUND_VOTE_RESULT.group.secondOption.percent, }, render: (args) => , }; @@ -26,9 +21,6 @@ export const 그룹_탭: Story = { export const 전체_탭: Story = { args: { isGroupTabActive: false, - roundResult: ROUND_VOTE_RESULT.total, - animatedFirstPercent: ROUND_VOTE_RESULT.total.firstOption.percent, - animatedSecondPercent: ROUND_VOTE_RESULT.total.secondOption.percent, }, render: (args) => , }; diff --git a/frontend/src/components/TabContentContainer/TabContentContainer.styled.ts b/frontend/src/components/TabContentContainer/TabContentContainer.styled.ts index 3230b1ad..37517cbe 100644 --- a/frontend/src/components/TabContentContainer/TabContentContainer.styled.ts +++ b/frontend/src/components/TabContentContainer/TabContentContainer.styled.ts @@ -43,7 +43,7 @@ export const barWrapperStyle = css` width: inherit; `; -export const barStyle = (percentage: number, isBigFirstOption: boolean) => css` +export const firstBar = (percentage: number, isBigFirstOption?: boolean) => css` display: flex; justify-content: center; align-items: center; @@ -62,7 +62,7 @@ export const barStyle = (percentage: number, isBigFirstOption: boolean) => css` transform: translateX(5px); `; -export const barBackgroundStyle = (percentage: number, isBigFirstOption: boolean) => css` +export const secondBar = (percentage: number, isBigFirstOption?: boolean) => css` display: flex; justify-content: center; align-items: center; diff --git a/frontend/src/components/TabContentContainer/TabContentContainer.tsx b/frontend/src/components/TabContentContainer/TabContentContainer.tsx index b658983e..50d4047c 100644 --- a/frontend/src/components/TabContentContainer/TabContentContainer.tsx +++ b/frontend/src/components/TabContentContainer/TabContentContainer.tsx @@ -2,40 +2,54 @@ import { useNavigate } from 'react-router-dom'; import { alertText, - barBackgroundStyle, - barStyle, barWrapperStyle, buttonStyle, categoryContainer, contentWrapperStyle, currentVoteButtonWrapper, + firstBar, resultTextStyle, roundVoteResultContainer, + secondBar, } from './TabContentContainer.styled'; +import { useTotalCountAnimation } from '../RoundVoteContainer/RoundVoteContainer.hook'; +import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; +import useRoundVoteResultQuery from '@/hooks/useRoundVoteResultQuery'; import { Group, Total } from '@/types/roundVoteResult'; +const isGroup = (value: Group | Total): value is Group => { + return 'memberCount' in value.firstOption; +}; + interface TabContentContainerProps { isGroupTabActive: boolean; - roundResult: Group | Total; - animatedFirstPercent?: number; - animatedSecondPercent?: number; } -const TabContentContainer = ({ - isGroupTabActive, - roundResult, - animatedFirstPercent, - animatedSecondPercent, -}: TabContentContainerProps) => { +const TabContentContainer = ({ isGroupTabActive }: TabContentContainerProps) => { const navigate = useNavigate(); + const { balanceContent } = useBalanceContentQuery(); + const { groupRoundResult, totalResult } = useRoundVoteResultQuery({ + roomId: 1, + contentId: balanceContent?.contentId, + }); - const isBigFirstOption = roundResult.firstOption.percent >= 50; + const { + animatedFirstPercent, + animatedSecondPercent, + animatedTotalFirstPercent, + animatedTotalSecondPercent, + } = useTotalCountAnimation(groupRoundResult, totalResult); + + const roundResult = isGroupTabActive ? groupRoundResult : totalResult; + const isBigFirstOption = roundResult && roundResult.firstOption.percent >= 50; const goToVoteStatus = () => { navigate('/round/result/status'); }; + if (!roundResult) return
    데이터가 없습니다
    ; + return (
    다른 사람들은 이렇게 생각했어요 🥜
    @@ -45,20 +59,16 @@ const TabContentContainer = ({ {roundResult.secondOption.name}
    - - {animatedFirstPercent}% + + {isGroup(roundResult) ? animatedFirstPercent : animatedTotalFirstPercent}% - - {animatedSecondPercent}% + + {isGroup(roundResult) ? animatedSecondPercent : animatedTotalSecondPercent}%
    - {'memberCount' in roundResult.firstOption && ( - {roundResult.firstOption.memberCount}명 - )} - {'memberCount' in roundResult.secondOption && ( - {roundResult.secondOption.memberCount}명 - )} + {isGroup(roundResult) && {roundResult.firstOption.memberCount}명} + {isGroup(roundResult) && {roundResult.secondOption.memberCount}명}
    From 8f3a7b3ff8efd7751806a0e869ad4d52cc1ce37b Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 1 Aug 2024 17:43:37 +0900 Subject: [PATCH 0412/1013] =?UTF-8?q?feat:=20API=20=EB=B3=80=EA=B2=BD?= =?UTF-8?q?=EC=97=90=20=EB=A7=9E=EC=B6=94=EC=96=B4=20Controller=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20#98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../balance/room/RoomController.java | 9 ++++----- .../balance/room/RoomControllerTest.java | 20 ++++--------------- .../balance/room/RoomDocumentationTest.java | 18 ++++------------- 3 files changed, 12 insertions(+), 35 deletions(-) diff --git a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java index 8b24da75..e1a03733 100644 --- a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java +++ b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java @@ -1,6 +1,5 @@ package ddangkong.controller.balance.room; -import ddangkong.controller.balance.content.dto.BalanceContentResponse; import ddangkong.controller.balance.room.dto.RoomInfoResponse; import ddangkong.controller.balance.room.dto.RoomJoinRequest; import ddangkong.controller.balance.room.dto.RoomJoinResponse; @@ -11,6 +10,7 @@ import org.springframework.http.HttpStatus; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -43,9 +43,8 @@ public RoomJoinResponse joinRoom(@PathVariable @Positive Long roomId, @Valid @Re return roomService.joinRoom(request.nickname(), roomId); } - @ResponseStatus(HttpStatus.CREATED) - @PostMapping("/balances/rooms/{roomId}/contents") - public BalanceContentResponse moveToNextRound(@PathVariable @Positive Long roomId) { - return roomService.moveToNextRound(roomId); + @PatchMapping("/balances/rooms/{roomId}/next") + public void moveToNextRound(@PathVariable @Positive Long roomId) { + roomService.moveToNextRound(roomId); } } diff --git a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java index 3dd04d50..97c86b3b 100644 --- a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java @@ -4,11 +4,8 @@ import static org.junit.jupiter.api.Assertions.assertAll; import ddangkong.controller.BaseControllerTest; -import ddangkong.controller.balance.content.dto.BalanceContentResponse; -import ddangkong.controller.balance.option.dto.BalanceOptionResponse; import ddangkong.controller.balance.room.dto.RoomInfoResponse; import ddangkong.controller.balance.room.dto.RoomJoinResponse; -import ddangkong.domain.balance.content.Category; import io.restassured.RestAssured; import io.restassured.http.ContentType; import java.util.HashMap; @@ -122,23 +119,14 @@ class 방_참가 { @Nested class 다음_라운드_진행 { - private static final BalanceContentResponse EXPECTED_RESPONSE = new BalanceContentResponse( - 3L, Category.EXAMPLE, 5, 3, "다음 중 여행가고 싶은 곳은?", - new BalanceOptionResponse(5L, "산"), - new BalanceOptionResponse(6L, "바다")); - @Test void 다음_라운드로_진행할_수_있다() { // when - BalanceContentResponse actual = RestAssured.given().log().all() + RestAssured.given().log().all() .pathParam("roomId", 1L) - .when().post("/api/balances/rooms/{roomId}/contents") + .when().patch("/api/balances/rooms/{roomId}/next") .then().log().all() - .statusCode(201) - .extract().as(BalanceContentResponse.class); - - // then - assertThat(actual).isEqualTo(EXPECTED_RESPONSE); + .statusCode(200); } @Test @@ -146,7 +134,7 @@ class 다음_라운드_진행 { // when & then RestAssured.given().log().all() .pathParam("roomId", -1L) - .when().post("/api/balances/rooms/{roomId}/contents") + .when().patch("/api/balances/rooms/{roomId}/next") .then().log().all() .statusCode(400); } diff --git a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java index 012f3e2d..16e775f7 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java @@ -6,6 +6,7 @@ import static org.mockito.Mockito.when; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; import static org.springframework.restdocs.payload.JsonFieldType.BOOLEAN; import static org.springframework.restdocs.payload.JsonFieldType.NUMBER; @@ -159,7 +160,7 @@ class 방_정보_조회 { @Nested class 다음_라운드로_이동 { - private static final String ENDPOINT = "/api/balances/rooms/{roomId}/contents"; + private static final String ENDPOINT = "/api/balances/rooms/{roomId}/next"; @Test void 다음_라운드로_이동한다() throws Exception { @@ -180,22 +181,11 @@ class 다음_라운드로_이동 { when(roomService.moveToNextRound(anyLong())).thenReturn(response); //then - mockMvc.perform(post(ENDPOINT, 1L)) - .andExpect(status().isCreated()) + mockMvc.perform(patch(ENDPOINT, 1L)) + .andExpect(status().isOk()) .andDo(document("room/next", pathParameters( parameterWithName("roomId").description("방 ID") - ), - responseFields( - fieldWithPath("contentId").type(NUMBER).description("콘텐츠 ID"), - fieldWithPath("category").type(STRING).description("콘텐츠 카테고리"), - fieldWithPath("totalRound").type(NUMBER).description("총 라운드 수"), - fieldWithPath("currentRound").type(NUMBER).description("현재 라운드"), - fieldWithPath("question").type(STRING).description("콘텐츠 질문"), - fieldWithPath("firstOption.optionId").type(NUMBER).description("첫 번째 선택지 ID"), - fieldWithPath("firstOption.name").type(STRING).description("첫 번째 선택지명"), - fieldWithPath("secondOption.optionId").type(NUMBER).description("두 번째 선택지 ID"), - fieldWithPath("secondOption.name").type(STRING).description("두 번째 선택지명") ) )); } From 086cd19d4b9432ec1520649b46b3a0449899f883 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Thu, 1 Aug 2024 17:55:29 +0900 Subject: [PATCH 0413/1013] =?UTF-8?q?feat:=20categoryContainer=20=EC=8A=A4?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=20=EB=B6=81=20=EC=B6=94=EA=B0=80=20#92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CategoryContainer.stories.ts | 16 ++++++++++++++++ .../CategoryContainer/CategoryContainer.tsx | 8 ++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 frontend/src/components/CategoryContainer/CategoryContainer.stories.ts diff --git a/frontend/src/components/CategoryContainer/CategoryContainer.stories.ts b/frontend/src/components/CategoryContainer/CategoryContainer.stories.ts new file mode 100644 index 00000000..76911391 --- /dev/null +++ b/frontend/src/components/CategoryContainer/CategoryContainer.stories.ts @@ -0,0 +1,16 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import CategoryContainer from './CategoryContainer'; + +const meta: Meta = { + component: CategoryContainer, +}; + +export const 기본값: Story = { + args: { + category: '연애', + }, +}; + +export default meta; +type Story = StoryObj; diff --git a/frontend/src/components/CategoryContainer/CategoryContainer.tsx b/frontend/src/components/CategoryContainer/CategoryContainer.tsx index a5f1e5f1..bb60a082 100644 --- a/frontend/src/components/CategoryContainer/CategoryContainer.tsx +++ b/frontend/src/components/CategoryContainer/CategoryContainer.tsx @@ -2,11 +2,15 @@ import React from 'react'; import { categoryContainerLayout, title, subtitle } from './CategoryContainer.styled'; -const CategoryContainer = () => { +interface CategoryContainerInterface { + category: string; +} + +const CategoryContainer = ({ category }: CategoryContainerInterface) => { return (

    카테고리

    -

    연애

    +

    {category}

    ); }; From 49fecd6b9de205a70dc04ccaa98c8f3e5ced6805 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Thu, 1 Aug 2024 18:03:52 +0900 Subject: [PATCH 0414/1013] =?UTF-8?q?feat:=20=EB=B0=A9=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EA=B0=80=EC=A0=B8=EC=98=A4=EA=B8=B0=20mocking=20#9?= =?UTF-8?q?2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/constants/url.ts | 6 ++-- frontend/src/mocks/data/roomAndMember.json | 8 +++++ frontend/src/mocks/data/roomMembers.json | 34 ++++++++++++++++++++++ frontend/src/mocks/handlers/roomHandler.ts | 11 +++++++ frontend/src/pages/ReadyPage/ReadyPage.tsx | 2 +- 5 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 frontend/src/mocks/data/roomAndMember.json create mode 100644 frontend/src/mocks/data/roomMembers.json create mode 100644 frontend/src/mocks/handlers/roomHandler.ts diff --git a/frontend/src/constants/url.ts b/frontend/src/constants/url.ts index 3c04d4e4..5efccd94 100644 --- a/frontend/src/constants/url.ts +++ b/frontend/src/constants/url.ts @@ -1,4 +1,4 @@ -const BASE_URL = process.env.API_BASE_URL; +const BASE_URL = `http://${process.env.API_BASE_URL}`; export const API_URL = { balanceContent: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/content`, @@ -9,7 +9,7 @@ export const API_URL = { moveNextRound: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/contents`, finalResult: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/final`, room: `${BASE_URL}/api/balances/rooms`, - roomMembers: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/members`, + roomMembers: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}`, }; export const MOCK_API_URL = { @@ -18,4 +18,6 @@ export const MOCK_API_URL = { roundVoteResult: '/api/balances/rooms/:roomId/contents/:contentId/vote-result', moveNextRound: '/api/balances/rooms/:roomId/contents', finalResult: '/api/balances/rooms/:roomId/final', + room: `${BASE_URL}/api/balances/rooms`, + roomMembers: `${BASE_URL}/api/balances/rooms/:roomId`, }; diff --git a/frontend/src/mocks/data/roomAndMember.json b/frontend/src/mocks/data/roomAndMember.json new file mode 100644 index 00000000..e95f7022 --- /dev/null +++ b/frontend/src/mocks/data/roomAndMember.json @@ -0,0 +1,8 @@ +{ + "roomId": 2, + "member": { + "memberId": 5, + "nickname": "든콩콩콩", + "isMaster": false + } +} diff --git a/frontend/src/mocks/data/roomMembers.json b/frontend/src/mocks/data/roomMembers.json new file mode 100644 index 00000000..2a3a8e23 --- /dev/null +++ b/frontend/src/mocks/data/roomMembers.json @@ -0,0 +1,34 @@ +{ + "isGameStart": false, + "roomSettings": { + "totalRound": 5, + "timeLimit": 10000 + }, + "members": [ + { + "memberId": 1, + "nickname": "든콩", + "isMaster": true + }, + { + "memberId": 2, + "nickname": "프콩", + "isMaster": false + }, + { + "memberId": 3, + "nickname": "프콩", + "isMaster": false + }, + { + "memberId": 4, + "nickname": "프콩", + "isMaster": false + }, + { + "memberId": 5, + "nickname": "프콩", + "isMaster": false + } + ] +} diff --git a/frontend/src/mocks/handlers/roomHandler.ts b/frontend/src/mocks/handlers/roomHandler.ts new file mode 100644 index 00000000..39ae7e6c --- /dev/null +++ b/frontend/src/mocks/handlers/roomHandler.ts @@ -0,0 +1,11 @@ +import { http, HttpResponse } from 'msw'; + +import ROOM_AND_MEMBER from '../data/roomAndMember.json'; +import ROOM_MEMBERS from '../data/roomMembers.json'; + +import { MOCK_API_URL } from '@/constants/url'; +import { RoomMembers } from '@/types/room'; + +export const roomHandler = [ + // http.get(MOCK_API_URL.roomMembers, () => HttpResponse.json(ROOM_MEMBERS)), +]; diff --git a/frontend/src/pages/ReadyPage/ReadyPage.tsx b/frontend/src/pages/ReadyPage/ReadyPage.tsx index 45bab533..67a0dbf7 100644 --- a/frontend/src/pages/ReadyPage/ReadyPage.tsx +++ b/frontend/src/pages/ReadyPage/ReadyPage.tsx @@ -25,7 +25,7 @@ const ReadyPage = () => { return (
    - + {isError &&
    에러 발생
    } {isLoading &&
    로딩중.......
    } {data && } From 6539d44293535c4feb1fd7e4dfd53de8314569cf Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Thu, 1 Aug 2024 18:09:00 +0900 Subject: [PATCH 0415/1013] =?UTF-8?q?refactor:=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=AA=85=20=EB=AA=85?= =?UTF-8?q?=ED=99=95=ED=95=98=EA=B2=8C=20=EC=88=98=EC=A0=95=20#93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/balance/room/RoomTest.java | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java index ccf39e8a..bbf58768 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java @@ -52,7 +52,7 @@ class 라운드_종료 { private static final RoomStatus FIXED_STATUS = RoomStatus.PROGRESS; @Test - void 나의_라운드가_종료되었으면_true를_반환한다() { + void 나의_라운드가_방의_현재_라운드보다_작으면_나의_라운드는_종료된_것이다() { // given int currentRound = 2; Room room = new Room(FIXED_TOTAL_ROUND, currentRound, FIXED_TIME_LIMIT, FIXED_STATUS); @@ -66,7 +66,7 @@ class 라운드_종료 { } @Test - void 나의_라운드가_종료되지_않았으면_false를_반환한다() { + void 나의_라운드와_방의_현재_라운드와_같으면_나의_라운드는_종료되지_않은_것이다() { // given int currentRound = 2; Room room = new Room(FIXED_TOTAL_ROUND, currentRound, FIXED_TIME_LIMIT, FIXED_STATUS); @@ -105,9 +105,10 @@ class 라운드_종료 { } @Test - void 전체_라운드가_종료되었으면_true를_반환한다() { + void 현재_라운드와_전체_라운드가_같고_방_상태가_FINISH이면_방의_전체_라운드가_종료된_것이다() { // given - Room room = new Room(FIXED_TOTAL_ROUND, 5, FIXED_TIME_LIMIT, RoomStatus.FINISH); + RoomStatus status = RoomStatus.FINISH; + Room room = new Room(FIXED_TOTAL_ROUND, 5, FIXED_TIME_LIMIT, status); // when boolean actual = room.isAllRoundFinished(); @@ -116,9 +117,23 @@ class 라운드_종료 { assertThat(actual).isTrue(); } + @Test + void 현재_라운드와_전체_라운드가_다르면_방의_전체_라운드가_종료되지_않은_것이다() { + // given + int currentRound = 3; + int totalRound = 5; + Room room = new Room(totalRound, currentRound, FIXED_TIME_LIMIT, FIXED_STATUS); + + // when + boolean actual = room.isAllRoundFinished(); + + // then + assertThat(actual).isFalse(); + } + @ParameterizedTest @EnumSource(value = RoomStatus.class, names = {"READY", "PROGRESS"}) - void 전체_라운드가_종료되지_않았으면_false를_반환한다(RoomStatus status) { + void 방_상태가_FINISH가_아니면_방의_전체_라운드가_종료되지_않은_것이다(RoomStatus status) { // given Room room = new Room(FIXED_TOTAL_ROUND, 5, FIXED_TIME_LIMIT, status); From e4fbd7e8efe7dfef6fa48a1ba79396501f1b65c2 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Thu, 1 Aug 2024 18:16:47 +0900 Subject: [PATCH 0416/1013] =?UTF-8?q?feat:=20totalRound,=20currentRound=20?= =?UTF-8?q?=EB=B9=84=EA=B5=90=20=EC=B6=94=EA=B0=80=20#93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/main/java/ddangkong/domain/balance/room/Room.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/Room.java b/backend/src/main/java/ddangkong/domain/balance/room/Room.java index 8013c6ea..882c5d4a 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/Room.java @@ -88,6 +88,6 @@ private void validateLessThanOrEqualToCurrentRound(int round) { } public boolean isAllRoundFinished() { - return status.isGameFinish(); + return currentRound == totalRound && status.isGameFinish(); } } From aef523fc33aeac9e2dceb9a20727d9bdf4270c69 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Thu, 1 Aug 2024 18:30:26 +0900 Subject: [PATCH 0417/1013] =?UTF-8?q?feat:=20=EA=B2=8C=EC=9E=84=EC=A2=85?= =?UTF-8?q?=EB=A3=8C=20=EC=97=AC=EB=B6=80=20field=20=EC=B6=94=EA=B0=80=20#?= =?UTF-8?q?93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/balance/room/RoomService.java | 5 +- .../room/dto/RoundFinishedResponse.java | 13 +--- .../balance/room/RoomControllerTest.java | 5 +- .../balance/room/RoomDocumentationTest.java | 5 +- .../service/balance/room/RoomServiceTest.java | 60 +++++++++++++++---- 5 files changed, 59 insertions(+), 29 deletions(-) diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index 5a677e20..a12d64d6 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -75,9 +75,6 @@ private RoomContent findCurrentRoomContent(Room room) { @Transactional(readOnly = true) public RoundFinishedResponse getMyRoundFinished(Long roomId, int myRound) { Room room = roomRepository.getById(roomId); - if (room.isAllRoundFinished()) { - return RoundFinishedResponse.allRoundFinished(); - } - return RoundFinishedResponse.myRoundFinished(room, myRound); + return new RoundFinishedResponse(room.isMyRoundFinished(myRound), room.isAllRoundFinished()); } } diff --git a/backend/src/main/java/ddangkong/service/balance/room/dto/RoundFinishedResponse.java b/backend/src/main/java/ddangkong/service/balance/room/dto/RoundFinishedResponse.java index ffea249a..b4974467 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/dto/RoundFinishedResponse.java +++ b/backend/src/main/java/ddangkong/service/balance/room/dto/RoundFinishedResponse.java @@ -1,16 +1,7 @@ package ddangkong.service.balance.room.dto; -import ddangkong.domain.balance.room.Room; - public record RoundFinishedResponse( - boolean isFinished + boolean isRoundFinished, + boolean isGameFinished ) { - - public static RoundFinishedResponse allRoundFinished() { - return new RoundFinishedResponse(true); - } - - public static RoundFinishedResponse myRoundFinished(Room room, int myRound) { - return new RoundFinishedResponse(room.isMyRoundFinished(myRound)); - } } diff --git a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java index f5db590b..ee464d36 100644 --- a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java @@ -168,7 +168,10 @@ class 나의_라운드_종료_여부 { .extract().as(RoundFinishedResponse.class); // then - assertThat(roundFinishedResponse.isFinished()).isTrue(); + assertAll( + () -> assertThat(roundFinishedResponse.isRoundFinished()).isTrue(), + () -> assertThat(roundFinishedResponse.isGameFinished()).isFalse() + ); } } } diff --git a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java index 6f04d82f..6ebef980 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java @@ -210,7 +210,7 @@ class 나의_라운드_종료_여부 { @Test void 나의_라운드가_종료되었는지_조회한다() throws Exception { // given - RoundFinishedResponse response = new RoundFinishedResponse(true); + RoundFinishedResponse response = new RoundFinishedResponse(true, false); when(roomService.getMyRoundFinished(anyLong(), anyInt())).thenReturn(response); // when & then @@ -226,7 +226,8 @@ class 나의_라운드_종료_여부 { parameterWithName("myRound").description("나의 라운드") ), responseFields( - fieldWithPath("isFinished").description("라운드 종료 여부") + fieldWithPath("isRoundFinished").description("나의 라운드 종료 여부"), + fieldWithPath("isGameFinished").description("게임 종료 여부") ) )); } diff --git a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java index 6683f0b4..641a255f 100644 --- a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java @@ -19,8 +19,6 @@ import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.CsvSource; import org.springframework.beans.factory.annotation.Autowired; class RoomServiceTest extends BaseServiceTest { @@ -145,33 +143,73 @@ class 나의_라운드_종료_여부 { private static final int FIXED_TIME_LIMIT = 30_000; private static final RoomStatus FIXED_STATUS = RoomStatus.PROGRESS; - @ParameterizedTest - @CsvSource(value = {"1, true", "2, false"}) - void 나의_라운드가_종료되었는지_조회한다(int myRound, boolean expected) { + @Test + void 나의_라운드가_종료되지_않았으면_게임도_종료되지_않은_상태이다() { + // given + int currentRound = 2; + Room room = roomRepository.save(new Room(FIXED_TOTAL_ROUND, currentRound, FIXED_TIME_LIMIT, FIXED_STATUS)); + int myRound = 2; + + // when + RoundFinishedResponse roundFinishedResponse = roomService.getMyRoundFinished(room.getId(), myRound); + + // then + assertAll( + () -> assertThat(roundFinishedResponse.isRoundFinished()).isFalse(), + () -> assertThat(roundFinishedResponse.isGameFinished()).isFalse() + ); + } + + @Test + void 나의_라운드가_종료되면_게임은_종료되지_않은_상태이다() { // given int currentRound = 2; Room room = roomRepository.save(new Room(FIXED_TOTAL_ROUND, currentRound, FIXED_TIME_LIMIT, FIXED_STATUS)); + int myRound = 1; // when RoundFinishedResponse roundFinishedResponse = roomService.getMyRoundFinished(room.getId(), myRound); // then - assertThat(roundFinishedResponse.isFinished()).isEqualTo(expected); + assertAll( + () -> assertThat(roundFinishedResponse.isRoundFinished()).isTrue(), + () -> assertThat(roundFinishedResponse.isGameFinished()).isFalse() + ); } @Test - void 모든_라운드가_종료됐으면_나의_라운드도_종료된다() { + void 게임이_종료되면_나의_라운드는_종료되지_않은_상태이다() { // given int currentRound = 5; - Room room = roomRepository.save( - new Room(FIXED_TOTAL_ROUND, currentRound, FIXED_TIME_LIMIT, RoomStatus.FINISH) + RoomStatus status = RoomStatus.FINISH; + Room room = roomRepository.save(new Room(FIXED_TOTAL_ROUND, currentRound, FIXED_TIME_LIMIT, status)); + int myRound = 5; + + // when + RoundFinishedResponse roundFinishedResponse = roomService.getMyRoundFinished(room.getId(), myRound); + + // then + assertAll( + () -> assertThat(roundFinishedResponse.isRoundFinished()).isFalse(), + () -> assertThat(roundFinishedResponse.isGameFinished()).isTrue() ); + } + + @Test + void 현재_마지막_라운드여도_게임이_종료되지_않은_상태이면_나의_라운드도_종료되지_않은_상태이다() { + // given + int currentRound = 5; + Room room = roomRepository.save(new Room(FIXED_TOTAL_ROUND, currentRound, FIXED_TIME_LIMIT, FIXED_STATUS)); + int myRound = 5; // when - RoundFinishedResponse roundFinishedResponse = roomService.getMyRoundFinished(room.getId(), 5); + RoundFinishedResponse roundFinishedResponse = roomService.getMyRoundFinished(room.getId(), myRound); // then - assertThat(roundFinishedResponse.isFinished()).isTrue(); + assertAll( + () -> assertThat(roundFinishedResponse.isRoundFinished()).isFalse(), + () -> assertThat(roundFinishedResponse.isGameFinished()).isFalse() + ); } } } From dca4626e85770e0f7f2010260eb71e70176619c0 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Thu, 1 Aug 2024 18:51:05 +0900 Subject: [PATCH 0418/1013] =?UTF-8?q?feat:=20=EB=82=98=EC=9D=98=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B4=EB=93=9C=EC=99=80=20=ED=98=84=EC=9E=AC=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B4=EB=93=9C=20=EC=B0=A8=EC=9D=B4=20=EB=B9=84?= =?UTF-8?q?=EA=B5=90=20#93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ddangkong/domain/balance/room/Room.java | 18 ++++++++++++++---- .../domain/balance/room/RoomTest.java | 13 +++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/Room.java b/backend/src/main/java/ddangkong/domain/balance/room/Room.java index 882c5d4a..32b1aa48 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/Room.java @@ -20,6 +20,7 @@ public class Room { private static final int DEFAULT_TOTAL_ROUND = 5; private static final int DEFAULT_TIME_LIMIT_MSEC = 30_000; private static final int START_ROUND = 1; + private static final int ALLOWED_ROUND_GAP = 1; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -38,10 +39,6 @@ public class Room { @Enumerated(EnumType.STRING) private RoomStatus status; - public static Room createNewRoom() { - return new Room(DEFAULT_TOTAL_ROUND, START_ROUND, DEFAULT_TIME_LIMIT_MSEC, RoomStatus.READY); - } - public Room(int totalRound, int currentRound, int timeLimit, RoomStatus status) { this.totalRound = totalRound; this.currentRound = currentRound; @@ -49,6 +46,10 @@ public Room(int totalRound, int currentRound, int timeLimit, RoomStatus status) this.status = status; } + public static Room createNewRoom() { + return new Room(DEFAULT_TOTAL_ROUND, START_ROUND, DEFAULT_TIME_LIMIT_MSEC, RoomStatus.READY); + } + public void moveToNextRound() { if (canMoveToNextRound()) { currentRound++; @@ -68,6 +69,7 @@ public boolean isGameProgress() { public boolean isMyRoundFinished(int myRound) { validateGreaterThanOrEqualToStartRound(myRound); validateLessThanOrEqualToCurrentRound(myRound); + validateDifferenceBetweenRoundAndCurrentRound(myRound); return currentRound != myRound; } @@ -87,6 +89,14 @@ private void validateLessThanOrEqualToCurrentRound(int round) { } } + private void validateDifferenceBetweenRoundAndCurrentRound(int round) { + if (round < currentRound && currentRound - round != 1) { + throw new BadRequestException("currentRound과 round의 차이는 %d이하여야 합니다. currentRound : %d, round : %d" + .formatted(ALLOWED_ROUND_GAP, currentRound, round) + ); + } + } + public boolean isAllRoundFinished() { return currentRound == totalRound && status.isGameFinish(); } diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java index bbf58768..040522bc 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java @@ -104,6 +104,19 @@ class 라운드_종료 { .hasMessageContaining("currentRound보다 작거나 같아야 합니다. currentRound : 1, round : 2"); } + @Test + void 나의_라운드가_방의_현재_라운드보다_2이상_작으면_예외가_발생한다() { + // given + int currentRound = 4; + Room room = new Room(FIXED_TOTAL_ROUND, currentRound, FIXED_TIME_LIMIT, FIXED_STATUS); + int invalidMyRound = 2; + + // when & then + assertThatThrownBy(() -> room.isMyRoundFinished(invalidMyRound)) + .isExactlyInstanceOf(BadRequestException.class) + .hasMessageContaining("currentRound과 round의 차이는 1이하여야 합니다. currentRound : 4, round : 2"); + } + @Test void 현재_라운드와_전체_라운드가_같고_방_상태가_FINISH이면_방의_전체_라운드가_종료된_것이다() { // given From 9ab67d434866453d5ee601ae28172e09526db3a1 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 1 Aug 2024 20:26:29 +0900 Subject: [PATCH 0419/1013] =?UTF-8?q?feat:=20=EB=A7=88=EC=A7=80=EB=A7=89?= =?UTF-8?q?=20=EB=9D=BC=EC=9A=B4=EB=93=9C=EC=97=90=EC=84=9C=20=EB=8B=A4?= =?UTF-8?q?=EC=9D=8C=20=EB=9D=BC=EC=9A=B4=EB=93=9C=EB=A1=9C=20=EB=84=98?= =?UTF-8?q?=EA=B8=B8=20=EA=B2=BD=EC=9A=B0=20=EA=B2=8C=EC=9E=84=EC=9D=84=20?= =?UTF-8?q?=EC=A2=85=EB=A3=8C=EC=8B=9C=ED=82=A8=EB=8B=A4=20#98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/BalanceContentRepository.java | 1 - .../ddangkong/domain/balance/room/Room.java | 13 +++-- .../service/balance/room/RoomService.java | 25 +-------- .../balance/room/RoomDocumentationTest.java | 20 +------ .../domain/balance/room/RoomTest.java | 37 ++++++++++--- .../service/balance/room/RoomServiceTest.java | 52 +++++++++++++++---- 6 files changed, 82 insertions(+), 66 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/content/BalanceContentRepository.java b/backend/src/main/java/ddangkong/domain/balance/content/BalanceContentRepository.java index 5ed28c7d..79fb9d09 100644 --- a/backend/src/main/java/ddangkong/domain/balance/content/BalanceContentRepository.java +++ b/backend/src/main/java/ddangkong/domain/balance/content/BalanceContentRepository.java @@ -1,6 +1,5 @@ package ddangkong.domain.balance.content; -import ddangkong.domain.balance.option.BalanceOption; import ddangkong.exception.BadRequestException; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/backend/src/main/java/ddangkong/domain/balance/room/Room.java b/backend/src/main/java/ddangkong/domain/balance/room/Room.java index 90c4bf9d..a6190e37 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/Room.java @@ -50,15 +50,18 @@ public Room(int totalRound, int currentRound, int timeLimit, RoomStatus status) } public void moveToNextRound() { - if (canMoveToNextRound()) { - currentRound++; + if (!isGameProgress()) { + throw new BadRequestException("게임이 진행 중이 아닙니다."); + } + if (isFinalRound()) { + status = RoomStatus.FINISH; return; } - throw new BadRequestException("마지막 라운드입니다."); + currentRound++; } - private boolean canMoveToNextRound() { - return currentRound < totalRound; + private boolean isFinalRound() { + return currentRound == totalRound; } public boolean isGameProgress() { diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index 58b4a970..fbb6d9a5 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -1,18 +1,12 @@ package ddangkong.service.balance.room; -import ddangkong.controller.balance.content.dto.BalanceContentResponse; import ddangkong.controller.balance.member.dto.MemberResponse; import ddangkong.controller.balance.room.dto.RoomInfoResponse; import ddangkong.controller.balance.room.dto.RoomJoinResponse; -import ddangkong.domain.balance.option.BalanceOptionRepository; -import ddangkong.domain.balance.option.BalanceOptions; import ddangkong.domain.balance.room.Room; -import ddangkong.domain.balance.room.RoomContent; -import ddangkong.domain.balance.room.RoomContentRepository; import ddangkong.domain.balance.room.RoomRepository; import ddangkong.domain.member.Member; import ddangkong.domain.member.MemberRepository; -import ddangkong.exception.BadRequestException; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -26,10 +20,6 @@ public class RoomService { private final MemberRepository memberRepository; - private final RoomContentRepository roomContentRepository; - - private final BalanceOptionRepository balanceOptionRepository; - @Transactional(readOnly = true) public RoomInfoResponse findRoomInfo(Long roomId) { Room room = roomRepository.getById(roomId); @@ -53,21 +43,8 @@ public RoomJoinResponse joinRoom(String nickname, Long roomId) { } @Transactional - public BalanceContentResponse moveToNextRound(Long roomId) { + public void moveToNextRound(Long roomId) { Room room = roomRepository.getById(roomId); room.moveToNextRound(); - - RoomContent roomContent = findCurrentRoomContent(room); - BalanceOptions balanceOptions = balanceOptionRepository.getBalanceOptionsByBalanceContent( - roomContent.getBalanceContent()); - return BalanceContentResponse.builder() - .roomContent(roomContent) - .balanceOptions(balanceOptions) - .build(); - } - - private RoomContent findCurrentRoomContent(Room room) { - return roomContentRepository.findByRoomAndRound(room, room.getCurrentRound()) - .orElseThrow(() -> new BadRequestException("해당 방의 현재 진행중인 질문이 존재하지 않습니다.")); } } diff --git a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java index 16e775f7..29b5b299 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java @@ -18,16 +18,13 @@ import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import ddangkong.controller.balance.content.dto.BalanceContentResponse; import ddangkong.controller.balance.member.dto.MemberResponse; -import ddangkong.controller.balance.option.dto.BalanceOptionResponse; import ddangkong.controller.balance.room.RoomController; import ddangkong.controller.balance.room.dto.RoomInfoResponse; import ddangkong.controller.balance.room.dto.RoomJoinRequest; import ddangkong.controller.balance.room.dto.RoomJoinResponse; import ddangkong.controller.balance.room.dto.RoomSettingResponse; import ddangkong.documentation.BaseDocumentationTest; -import ddangkong.domain.balance.content.Category; import ddangkong.service.balance.room.RoomService; import java.util.List; import org.junit.jupiter.api.Nested; @@ -164,23 +161,8 @@ class 다음_라운드로_이동 { @Test void 다음_라운드로_이동한다() throws Exception { - //given - BalanceOptionResponse firstOption = new BalanceOptionResponse(3L, "10년 동안 한 사람과 연애한 애인"); - BalanceOptionResponse secondOption = new BalanceOptionResponse(4L, "1년 동안 다섯 사람과 연애한 애인"); - BalanceContentResponse response = new BalanceContentResponse( - 2L, - Category.EXAMPLE, - 5, - 2, - "10년 동안 한 사람과 연애한 애인 VS 1년 동안 다섯 사람과 연애한 애인", - firstOption, - secondOption - ); - - //when - when(roomService.moveToNextRound(anyLong())).thenReturn(response); - //then + // when & then mockMvc.perform(patch(ENDPOINT, 1L)) .andExpect(status().isOk()) .andDo(document("room/next", diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java index 2cde8032..f20ad926 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java @@ -2,10 +2,13 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertAll; import ddangkong.exception.BadRequestException; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; class RoomTest { @@ -16,8 +19,10 @@ class 다음_라운드로_이동 { @Test void 다음_라운드로_이동할_수_있다() { // given - Room room = Room.createNewRoom(); - int currentRound = room.getCurrentRound(); + int totalRound = 5; + int currentRound = 1; + int timeLimit = 30_000; + Room room = new Room(totalRound, currentRound, timeLimit, RoomStatus.PROGRESS); int expectedRound = currentRound + 1; // when @@ -28,17 +33,37 @@ class 다음_라운드로_이동 { } @Test - void 마지막_라운드_일_경우_예외를_던진다() { + void 마지막_라운드_일_경우_게임을_종료한다() { // given int totalRound = 5; int currentRound = 5; - int timeLimit = 30000; - Room room = new Room(totalRound, currentRound, timeLimit, RoomStatus.PROGRESS); + int timeLimit = 30_000; + RoomStatus status = RoomStatus.PROGRESS; + Room room = new Room(totalRound, currentRound, timeLimit, status); + + // when + room.moveToNextRound(); + + // then + assertAll( + () -> assertThat(room.getCurrentRound()).isEqualTo(totalRound), + () -> assertThat(room.getStatus()).isEqualTo(RoomStatus.FINISH) + ); + } + + @ParameterizedTest + @CsvSource({"READY", "FINISH"}) + void 게임이_진행_중이_아닐_경우_예외를_던진다(RoomStatus status) { + // given + int totalRound = 5; + int currentRound = 5; + int timeLimit = 30_000; + Room room = new Room(totalRound, currentRound, timeLimit, status); // when & then assertThatThrownBy(room::moveToNextRound) .isInstanceOf(BadRequestException.class) - .hasMessage("마지막 라운드입니다."); + .hasMessage("게임이 진행 중이 아닙니다."); } } } diff --git a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java index 374e1852..7edc877e 100644 --- a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java @@ -10,6 +10,9 @@ import ddangkong.controller.balance.room.dto.RoomInfoResponse; import ddangkong.controller.balance.room.dto.RoomJoinResponse; import ddangkong.domain.balance.content.Category; +import ddangkong.domain.balance.room.Room; +import ddangkong.domain.balance.room.RoomRepository; +import ddangkong.domain.balance.room.RoomStatus; import ddangkong.exception.BadRequestException; import ddangkong.service.BaseServiceTest; import org.assertj.core.api.Assertions; @@ -22,6 +25,9 @@ class RoomServiceTest extends BaseServiceTest { @Autowired private RoomService roomService; + @Autowired + private RoomRepository roomRepository; + @Nested class 게임_방_정보_조회 { @@ -96,6 +102,7 @@ class 방_참여 { class 다음_라운드로_이동 { private static final Long PROGRESS_ROOM_ID = 1L; + private static final int CURRENT_ROUND = 2; private static final Long NOT_EXIST_ROOM_ID = 999999999L; private static final Long NOT_PROGRESSED_ROOM_ID = 2L; private static final BalanceContentResponse BALANCE_CONTENT_RESPONSE = new BalanceContentResponse( @@ -104,28 +111,51 @@ class 다음_라운드로_이동 { new BalanceOptionResponse(6L, "바다")); @Test - void 다음_라운드로_넘어갈_수_있다() { + void 중간_라운드라면_다음_라운드로_넘어갈_수_있다() { + // given + int nextRound = CURRENT_ROUND + 1; + // when - BalanceContentResponse actual = roomService.moveToNextRound(PROGRESS_ROOM_ID); + roomService.moveToNextRound(PROGRESS_ROOM_ID); // then - assertThat(actual).isEqualTo(BALANCE_CONTENT_RESPONSE); + Room room = roomRepository.getById(PROGRESS_ROOM_ID); + assertAll( + () -> assertThat(room.getCurrentRound()).isEqualTo(nextRound), + () -> assertThat(room.isGameProgress()).isTrue() + ); } @Test - void 방이_없을_경우_예외를_던진다() { - // when & then - assertThatThrownBy(() -> roomService.moveToNextRound(NOT_EXIST_ROOM_ID)) - .isInstanceOf(BadRequestException.class) - .hasMessage("해당 방이 존재하지 않습니다."); + void 마지막_라운드라면_게임을_종료한다() { + // given + moveToFinalRound(PROGRESS_ROOM_ID); + + // when + roomService.moveToNextRound(PROGRESS_ROOM_ID); + + // then + Room room = roomRepository.getById(PROGRESS_ROOM_ID); + assertAll( + () -> assertThat(room.getCurrentRound()).isEqualTo(room.getTotalRound()), + () -> assertThat(room.getStatus()).isEqualTo(RoomStatus.FINISH) + ); + } + + void moveToFinalRound(Long roomId) { + Room room = roomRepository.getById(roomId); + int countOfMoving = room.getTotalRound() - room.getCurrentRound(); + for (int count = 0; count < countOfMoving; count++) { + roomService.moveToNextRound(PROGRESS_ROOM_ID); + } } @Test - void 방의_현재_라운드의_질문이_없을_경우_예외를_던진다() { + void 방이_없을_경우_예외를_던진다() { // when & then - assertThatThrownBy(() -> roomService.moveToNextRound(NOT_PROGRESSED_ROOM_ID)) + assertThatThrownBy(() -> roomService.moveToNextRound(NOT_EXIST_ROOM_ID)) .isInstanceOf(BadRequestException.class) - .hasMessage("해당 방의 현재 진행중인 질문이 존재하지 않습니다."); + .hasMessage("해당 방이 존재하지 않습니다."); } } } From 3ec3dccc3adf101fd56bfdd05866ef4caa0037fc Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 1 Aug 2024 21:37:04 +0900 Subject: [PATCH 0420/1013] =?UTF-8?q?feat:=20timer=EC=99=80=20width?= =?UTF-8?q?=EA=B0=92=EC=9D=84=20state=EB=A1=9C=20=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=ED=95=98=EC=97=AC=20=EC=9D=B4=EB=8F=99=ED=95=98=EB=8A=94=20ani?= =?UTF-8?q?mation=20=EC=A0=81=EC=9A=A9=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/Timer/Timer.styled.ts | 46 +++++++++++++++++-- frontend/src/components/Timer/Timer.tsx | 43 ++++++++++++++++- frontend/src/components/Timer/Timer.util.ts | 9 ++++ 3 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 frontend/src/components/Timer/Timer.util.ts diff --git a/frontend/src/components/Timer/Timer.styled.ts b/frontend/src/components/Timer/Timer.styled.ts index 40f10dea..1c27d9d2 100644 --- a/frontend/src/components/Timer/Timer.styled.ts +++ b/frontend/src/components/Timer/Timer.styled.ts @@ -4,12 +4,50 @@ import { Theme } from '@/styles/Theme'; export const timerLayout = css` display: flex; + position: relative; flex-basis: 5%; - justify-content: center; + align-items: center; width: 100%; height: 3.2rem; - border: none; + padding: 0 1rem; + border-radius: ${Theme.borderRadius.radius30}; + + background-color: ${Theme.color.peanut200}; + box-sizing: border-box; +`; + +export const timerInnerLayout = (width: number) => css` + display: flex; + justify-content: center; + align-items: center; + width: ${width}%; + height: 60%; + border-radius: ${Theme.borderRadius.radius30}; + + background-color: ${Theme.color.peanut500}; + transition: width 1s linear; +`; + +export const timerWrapper = (width: number) => css` + display: flex; + position: absolute; + right: ${100 - width}%; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 2rem; + height: 4rem; + transition: all 1s linear; +`; + +export const timerIcon = css` + position: absolute; +`; + +export const timerText = css` + position: absolute; + top: 5.2rem; - background: linear-gradient(to right, ${Theme.color.peanut500}, ${Theme.color.peanut300}); - border-radius: 1.7rem; + font-weight: bold; + font-size: 1.6rem; `; diff --git a/frontend/src/components/Timer/Timer.tsx b/frontend/src/components/Timer/Timer.tsx index 57dcfa20..5d2285a8 100644 --- a/frontend/src/components/Timer/Timer.tsx +++ b/frontend/src/components/Timer/Timer.tsx @@ -1,7 +1,46 @@ -import { timerLayout } from './Timer.styled'; +import { useEffect, useRef, useState } from 'react'; + +import { timerIcon, timerInnerLayout, timerLayout, timerText, timerWrapper } from './Timer.styled'; +import { formatTimer } from './Timer.util'; + +import HOME_ICON from '@/assets/images/homeIcon.svg'; + +const INITIAL_TIMER = 30; +const INITIAL_WIDTH = 100; const Timer = () => { - return
    ; + const [timer, setTimer] = useState(INITIAL_TIMER); + const [width, setWidth] = useState(INITIAL_WIDTH); + const timeout = useRef(); + + useEffect(() => { + if (timer <= 0) { + clearInterval(timeout.current); + } + }, [timer]); + + useEffect(() => { + timeout.current = setInterval(() => { + setTimer((prev) => prev - 1); + setWidth((prevWidth) => (prevWidth > 0 ? prevWidth - INITIAL_WIDTH / INITIAL_TIMER : 0)); + }, 1000); + + return () => { + clearInterval(timeout.current); + }; + }, []); + + return ( + <> +
    +
    +
    + 타이머 + {formatTimer(timer)} +
    +
    + + ); }; export default Timer; diff --git a/frontend/src/components/Timer/Timer.util.ts b/frontend/src/components/Timer/Timer.util.ts new file mode 100644 index 00000000..65295eca --- /dev/null +++ b/frontend/src/components/Timer/Timer.util.ts @@ -0,0 +1,9 @@ +export const formatTimer = (timer: number) => { + const minutes = Math.floor(timer / 60); + const seconds = timer % 60; + + const formattedMinutes = String(minutes).padStart(2, '0'); + const formattedSeconds = String(seconds).padStart(2, '0'); + + return `${formattedMinutes}:${formattedSeconds}`; +}; From 99e41852b8dc34b284dc5b907748e420995d8c1f Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 1 Aug 2024 21:39:32 +0900 Subject: [PATCH 0421/1013] =?UTF-8?q?feat:=20=EB=B0=B8=EB=9F=B0=EC=8A=A4?= =?UTF-8?q?=20=EC=BB=A8=ED=85=90=EC=B8=A0=20=EC=A1=B0=ED=9A=8C=EB=A5=BC=20?= =?UTF-8?q?=EC=A0=9C=EC=99=B8=ED=95=9C=20=EB=B9=84=EC=A6=88=EB=8B=88?= =?UTF-8?q?=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84=20#99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/balance/room/RoomContent.java | 21 +++++++++++++++++++ .../service/balance/room/RoomService.java | 15 +++++++++++++ 2 files changed, 36 insertions(+) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java index 22ab7f88..cb40709b 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java @@ -11,6 +11,9 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.IntStream; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -35,6 +38,24 @@ public class RoomContent extends BaseEntity { @Column(nullable = false) private int round; + private LocalDateTime roundEndedAt; + + @Column(nullable = false) + private boolean isUsed; + + public static List createList(Room room, List balanceContents) { + return IntStream.range(0, balanceContents.size()) + .mapToObj(index -> new RoomContent(room, balanceContents.get(index), index + 1)) + .toList(); + } + + private RoomContent(Room room, BalanceContent balanceContent, int round) { + this.room = room; + this.balanceContent = balanceContent; + this.round = round; + this.isUsed = false; + } + public Long getContentId() { return balanceContent.getId(); } diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index 58b4a970..58404cd8 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -4,6 +4,7 @@ import ddangkong.controller.balance.member.dto.MemberResponse; import ddangkong.controller.balance.room.dto.RoomInfoResponse; import ddangkong.controller.balance.room.dto.RoomJoinResponse; +import ddangkong.domain.balance.content.BalanceContent; import ddangkong.domain.balance.option.BalanceOptionRepository; import ddangkong.domain.balance.option.BalanceOptions; import ddangkong.domain.balance.room.Room; @@ -70,4 +71,18 @@ private RoomContent findCurrentRoomContent(Room room) { return roomContentRepository.findByRoomAndRound(room, room.getCurrentRound()) .orElseThrow(() -> new BadRequestException("해당 방의 현재 진행중인 질문이 존재하지 않습니다.")); } + + @Transactional + public void startGame(Long roomId) { + Room room = roomRepository.getById(roomId); + room.startGame(); + + List balanceContents = findContents(room); + List roomContents = RoomContent.createList(room, balanceContents); + roomContentRepository.saveAll(roomContents); + } + + private List findContents(Room room) { + return List.of(); // TODO 랜덤 N개 조회 로직 구현 + } } From 31f77ea065ab3c57754a8cc8fea4f5bdd4b79b7a Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 1 Aug 2024 21:47:27 +0900 Subject: [PATCH 0422/1013] =?UTF-8?q?fix:=20response=20body=EC=97=90=20?= =?UTF-8?q?=EB=82=B4=EC=9A=A9=EC=9D=B4=20=EC=97=86=EC=9C=BC=EB=AF=80?= =?UTF-8?q?=EB=A1=9C,=20response=20status=EB=A5=BC=20No=20Content=EB=A1=9C?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20#98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ddangkong/controller/balance/room/RoomController.java | 1 + .../ddangkong/controller/balance/room/RoomControllerTest.java | 2 +- .../documentation/balance/room/RoomDocumentationTest.java | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java index e1a03733..12a4d3e3 100644 --- a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java +++ b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java @@ -43,6 +43,7 @@ public RoomJoinResponse joinRoom(@PathVariable @Positive Long roomId, @Valid @Re return roomService.joinRoom(request.nickname(), roomId); } + @ResponseStatus(HttpStatus.NO_CONTENT) @PatchMapping("/balances/rooms/{roomId}/next") public void moveToNextRound(@PathVariable @Positive Long roomId) { roomService.moveToNextRound(roomId); diff --git a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java index 97c86b3b..ecf0882d 100644 --- a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java @@ -126,7 +126,7 @@ class 다음_라운드_진행 { .pathParam("roomId", 1L) .when().patch("/api/balances/rooms/{roomId}/next") .then().log().all() - .statusCode(200); + .statusCode(204); } @Test diff --git a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java index 29b5b299..9be4b6c8 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java @@ -164,7 +164,7 @@ class 다음_라운드로_이동 { // when & then mockMvc.perform(patch(ENDPOINT, 1L)) - .andExpect(status().isOk()) + .andExpect(status().isNoContent()) .andDo(document("room/next", pathParameters( parameterWithName("roomId").description("방 ID") From 6c4f8cb8fbc70f41284239bfb867962a9d3ede5e Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 1 Aug 2024 21:53:25 +0900 Subject: [PATCH 0423/1013] =?UTF-8?q?feat:=205=EC=B4=88=20=EB=82=A8?= =?UTF-8?q?=EC=95=98=EC=9D=84=20=EB=95=8C=20font=EC=99=80=20rotate=20?= =?UTF-8?q?=EC=95=A0=EB=8B=88=EB=A9=94=EC=9D=B4=EC=85=98=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/Timer/Timer.styled.ts | 39 ++++++++++++++++++- frontend/src/components/Timer/Timer.tsx | 21 ++++++++-- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/Timer/Timer.styled.ts b/frontend/src/components/Timer/Timer.styled.ts index 1c27d9d2..6045b95e 100644 --- a/frontend/src/components/Timer/Timer.styled.ts +++ b/frontend/src/components/Timer/Timer.styled.ts @@ -1,7 +1,37 @@ -import { css } from '@emotion/react'; +import { css, keyframes } from '@emotion/react'; import { Theme } from '@/styles/Theme'; +const shake = keyframes` + 0%{ + transform: rotate(0deg); + } + 10%{ + transform: scale(1.5) rotate(45deg); + } + 20%{ + transform: scale(1.5) rotate(-45deg); + } + 30%{ + transform: rotate(30deg); + } + 40%{ + transform: rotate(-30deg); + } + 50%{ + transform: rotate(10deg); + } + 60%{ + transform: rotate(-10deg); + } + 70%{ + transform: rotate(0deg); + } + 100%{ + transform: rotate(0deg); + } +`; + export const timerLayout = css` display: flex; position: relative; @@ -44,10 +74,15 @@ export const timerIcon = css` position: absolute; `; -export const timerText = css` +export const timerIconShake = css` + animation: ${shake} 1s linear infinite; +`; + +export const timerText = (isAlmostFinished: boolean) => css` position: absolute; top: 5.2rem; + color: ${isAlmostFinished ? 'red' : 'black'}; font-weight: bold; font-size: 1.6rem; `; diff --git a/frontend/src/components/Timer/Timer.tsx b/frontend/src/components/Timer/Timer.tsx index 5d2285a8..f621d215 100644 --- a/frontend/src/components/Timer/Timer.tsx +++ b/frontend/src/components/Timer/Timer.tsx @@ -1,6 +1,13 @@ import { useEffect, useRef, useState } from 'react'; -import { timerIcon, timerInnerLayout, timerLayout, timerText, timerWrapper } from './Timer.styled'; +import { + timerIcon, + timerIconShake, + timerInnerLayout, + timerLayout, + timerText, + timerWrapper, +} from './Timer.styled'; import { formatTimer } from './Timer.util'; import HOME_ICON from '@/assets/images/homeIcon.svg'; @@ -11,6 +18,8 @@ const INITIAL_WIDTH = 100; const Timer = () => { const [timer, setTimer] = useState(INITIAL_TIMER); const [width, setWidth] = useState(INITIAL_WIDTH); + const isAlmostFinished = timer <= 5; + const timeout = useRef(); useEffect(() => { @@ -35,8 +44,14 @@ const Timer = () => {
    - 타이머 - {formatTimer(timer)} + 타이머 + {formatTimer(timer)}
    From 8aba069e300e90fa62d20707dfbf7120e9ea1f5a Mon Sep 17 00:00:00 2001 From: novice0840 Date: Thu, 1 Aug 2024 22:17:40 +0900 Subject: [PATCH 0424/1013] =?UTF-8?q?feat:=20=EB=8C=80=EA=B8=B0=EB=B0=A9?= =?UTF-8?q?=20polling=20=EC=97=B0=EB=8F=99=20#92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/room.ts | 4 +- .../CategoryContainer/CategoryContainer.tsx | 4 +- .../ReadyMembersContainer.tsx | 41 +++---------------- frontend/src/mocks/handlers/roomHandler.ts | 2 +- .../pages/NicknamePage/NicknamePage.styled.ts | 2 +- .../src/pages/NicknamePage/NicknamePage.tsx | 20 ++++----- frontend/src/pages/ReadyPage/ReadyPage.tsx | 2 +- frontend/src/types/room.ts | 15 ++++++- 8 files changed, 34 insertions(+), 56 deletions(-) diff --git a/frontend/src/apis/room.ts b/frontend/src/apis/room.ts index e386b34f..76a08157 100644 --- a/frontend/src/apis/room.ts +++ b/frontend/src/apis/room.ts @@ -1,7 +1,7 @@ import fetcher from './fetcher'; import { API_URL } from '@/constants/url'; -import { RoomAndMember, RoomMembers } from '@/types/room'; +import { RoomInfo, RoomMembers, RoomAndMember } from '@/types/room'; // 방 만들기 export const makeRoom = async (nickname: string): Promise => { @@ -25,7 +25,7 @@ export const makeRoom = async (nickname: string): Promise => { }; // 방 참여하기 -export const enterRoom = async (roomId: number, nickname: string): Promise => { +export const enterRoom = async (roomId: number, nickname: string): Promise => { const res = await fetcher.post({ url: API_URL.roomMembers(roomId), headers: { diff --git a/frontend/src/components/CategoryContainer/CategoryContainer.tsx b/frontend/src/components/CategoryContainer/CategoryContainer.tsx index bb60a082..5341872e 100644 --- a/frontend/src/components/CategoryContainer/CategoryContainer.tsx +++ b/frontend/src/components/CategoryContainer/CategoryContainer.tsx @@ -2,11 +2,11 @@ import React from 'react'; import { categoryContainerLayout, title, subtitle } from './CategoryContainer.styled'; -interface CategoryContainerInterface { +interface CategoryContainerProps { category: string; } -const CategoryContainer = ({ category }: CategoryContainerInterface) => { +const CategoryContainer = ({ category }: CategoryContainerProps) => { return (

    카테고리

    diff --git a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx index 362768e0..f1bc7911 100644 --- a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx +++ b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx @@ -7,42 +7,11 @@ import { memberStatus, } from './ReadyMembersContainer.styled'; -const example = { - isGameStart: false, - roomSettings: { - totalRound: 5, - timeLimit: 10000, - }, - members: [ - { - memberId: 1, - nickname: '든콩', - isMaster: true, - }, - { - memberId: 2, - nickname: '프콩', - isMaster: false, - }, - { - memberId: 3, - nickname: '프콩', - isMaster: false, - }, - { - memberId: 4, - nickname: '프콩', - isMaster: false, - }, - { - memberId: 5, - nickname: '프콩', - isMaster: false, - }, - ], -}; +import { RoomMembers } from '@/types/room'; + +interface ReadyMembersContainerProps extends RoomMembers {} -const ReadyMembersContainer = () => { +const ReadyMembersContainer = ({ members }: ReadyMembersContainerProps) => { return ( <>
    총 인원 5명
    @@ -52,7 +21,7 @@ const ReadyMembersContainer = () => {
    +
    초대하기
    - {example.members.map((member) => ( + {members.map((member) => (
  • +
    diff --git a/frontend/src/mocks/handlers/roomHandler.ts b/frontend/src/mocks/handlers/roomHandler.ts index 39ae7e6c..3bc693d0 100644 --- a/frontend/src/mocks/handlers/roomHandler.ts +++ b/frontend/src/mocks/handlers/roomHandler.ts @@ -1,6 +1,6 @@ import { http, HttpResponse } from 'msw'; -import ROOM_AND_MEMBER from '../data/roomAndMember.json'; +// import ROOM_AND_MEMBER from '../data/RoomInfo.json'; import ROOM_MEMBERS from '../data/roomMembers.json'; import { MOCK_API_URL } from '@/constants/url'; diff --git a/frontend/src/pages/NicknamePage/NicknamePage.styled.ts b/frontend/src/pages/NicknamePage/NicknamePage.styled.ts index 30879a11..6e2a8311 100644 --- a/frontend/src/pages/NicknamePage/NicknamePage.styled.ts +++ b/frontend/src/pages/NicknamePage/NicknamePage.styled.ts @@ -11,7 +11,7 @@ export const profile = css` background-color: ${Theme.color.gray300}; `; -export const nickname = css` +export const nicknameBox = css` width: 26.8rem; margin: 2rem 0; diff --git a/frontend/src/pages/NicknamePage/NicknamePage.tsx b/frontend/src/pages/NicknamePage/NicknamePage.tsx index bc47a83d..ed56bbf4 100644 --- a/frontend/src/pages/NicknamePage/NicknamePage.tsx +++ b/frontend/src/pages/NicknamePage/NicknamePage.tsx @@ -3,13 +3,13 @@ import { useRef } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; import { useRecoilState } from 'recoil'; -import { profile, nickname, nicknameInputWrapper, nicknameInput } from './NicknamePage.styled'; +import { profile, nicknameBox, nicknameInputWrapper, nicknameInput } from './NicknamePage.styled'; import { enterRoom, makeRoom } from '@/apis/room'; import Button from '@/components/common/Button/Button'; import Content from '@/components/layout/Content/Content'; import { memberInfoState } from '@/recoil/atom'; -import { RoomAndMember } from '@/types/room'; +import { RoomAndMember, RoomInfo } from '@/types/room'; import { createRandomNickname } from '@/utils/nickname'; const NicknamePage = () => { @@ -29,15 +29,13 @@ const NicknamePage = () => { onError: (error: Error) => {}, }); - const enterRoomMutation = useMutation( - { - mutationFn: ({ nickname, roomId }) => enterRoom(roomId, nickname), - onSuccess: (data) => { - navigate(`/ready?roomId=${data.roomId}`); - }, - onError: (error: Error) => {}, + const enterRoomMutation = useMutation({ + mutationFn: ({ nickname, roomId }) => enterRoom(roomId, nickname), + onSuccess: () => { + navigate(`/ready?roomId=${roomId}`); }, - ); + onError: (error: Error) => {}, + }); const handleClick = () => { if (isMaster) { @@ -50,7 +48,7 @@ const NicknamePage = () => { return (
    -
    닉네임
    +
    닉네임
    { {isError &&
    에러 발생
    } {isLoading &&
    로딩중.......
    } - {data && } + {data && }
    ); diff --git a/frontend/src/types/room.ts b/frontend/src/types/room.ts index bcfe2668..fc2ca827 100644 --- a/frontend/src/types/room.ts +++ b/frontend/src/types/room.ts @@ -4,11 +4,22 @@ interface Member { isMaster: boolean; } -export interface RoomAndMember { - roomId: number; +interface RoomSetting { + totalRound: number; + timeLimit: number; +} + +export interface RoomInfo { + isGameStart: boolean; + roomSetting: RoomSetting; member: Member; } export interface RoomMembers { members: Member[]; } + +export interface RoomAndMember { + roomId: number; + member: Member; +} From 044d80ba088e12d579cc5198e123c9270e069fe0 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Thu, 1 Aug 2024 22:50:39 +0900 Subject: [PATCH 0425/1013] =?UTF-8?q?fix:=20API=20=EC=A3=BC=EC=86=8C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20#92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/room.ts | 2 +- frontend/src/constants/url.ts | 1 + frontend/src/pages/ReadyPage/ReadyPage.tsx | 10 ++++++++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/frontend/src/apis/room.ts b/frontend/src/apis/room.ts index 76a08157..f270a317 100644 --- a/frontend/src/apis/room.ts +++ b/frontend/src/apis/room.ts @@ -27,7 +27,7 @@ export const makeRoom = async (nickname: string): Promise => { // 방 참여하기 export const enterRoom = async (roomId: number, nickname: string): Promise => { const res = await fetcher.post({ - url: API_URL.roomMembers(roomId), + url: API_URL.enterRoom(roomId), headers: { 'Content-Type': `application/json`, }, diff --git a/frontend/src/constants/url.ts b/frontend/src/constants/url.ts index 5efccd94..9d1cfa17 100644 --- a/frontend/src/constants/url.ts +++ b/frontend/src/constants/url.ts @@ -9,6 +9,7 @@ export const API_URL = { moveNextRound: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/contents`, finalResult: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/final`, room: `${BASE_URL}/api/balances/rooms`, + enterRoom: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/members`, roomMembers: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}`, }; diff --git a/frontend/src/pages/ReadyPage/ReadyPage.tsx b/frontend/src/pages/ReadyPage/ReadyPage.tsx index 8af6e4be..2d4fab52 100644 --- a/frontend/src/pages/ReadyPage/ReadyPage.tsx +++ b/frontend/src/pages/ReadyPage/ReadyPage.tsx @@ -12,7 +12,6 @@ import { QUERY_KEYS } from '@/constants/queryKeys'; import { memberInfoState } from '@/recoil/atom'; const ReadyPage = () => { - const handleClick = () => {}; const memberInfo = useRecoilValue(memberInfoState); const { search } = useLocation(); const roomId = Number(new URLSearchParams(search).get('roomId')); @@ -23,13 +22,20 @@ const ReadyPage = () => { refetchInterval: 1000, }); + const handleGameStart = () => { + if (memberInfo.isMaster) { + // TODO: 게임 시작 API 연결 예정 + alert('Game Start'); + } + }; + return (
    {isError &&
    에러 발생
    } {isLoading &&
    로딩중.......
    } {data && } -
    ); }; From 9f8b750b882712d296f2e7c6db771ce9a994e144 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Fri, 2 Aug 2024 00:13:34 +0900 Subject: [PATCH 0426/1013] =?UTF-8?q?refactor:=20=EC=A0=9C=ED=95=9C=20?= =?UTF-8?q?=EC=8B=9C=EA=B0=84=20=EB=8B=A8=EC=9C=84=20second=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20#93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/test/java/ddangkong/domain/balance/room/RoomTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java index 040522bc..6da1f7b6 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java @@ -48,7 +48,7 @@ class 다음_라운드로_이동 { class 라운드_종료 { private static final int FIXED_TOTAL_ROUND = 5; - private static final int FIXED_TIME_LIMIT = 30_000; + private static final int FIXED_TIME_LIMIT = 30; private static final RoomStatus FIXED_STATUS = RoomStatus.PROGRESS; @Test From 8d879ae36378b01f6a32e9422d0a8fce85e01200 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Fri, 2 Aug 2024 00:14:17 +0900 Subject: [PATCH 0427/1013] =?UTF-8?q?refactor:=20Timer=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=9D=98=20=EB=B9=84=EC=A6=88?= =?UTF-8?q?=EB=8B=88=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20=ED=9B=85=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B6=84=EB=A6=AC=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/Timer/Timer.hook.ts | 33 +++++++++++++ frontend/src/components/Timer/Timer.tsx | 55 ++++++--------------- frontend/src/pages/GamePage/GamePage.tsx | 12 ++--- 3 files changed, 52 insertions(+), 48 deletions(-) create mode 100644 frontend/src/components/Timer/Timer.hook.ts diff --git a/frontend/src/components/Timer/Timer.hook.ts b/frontend/src/components/Timer/Timer.hook.ts new file mode 100644 index 00000000..0b1f7515 --- /dev/null +++ b/frontend/src/components/Timer/Timer.hook.ts @@ -0,0 +1,33 @@ +import { useEffect, useRef, useState } from 'react'; + +const INITIAL_TIMER = 30; // TODO: tanstack-query로 timeLimit 서버 데이터 받아오기 +const INITIAL_WIDTH = 100; + +const useRoundTimer = () => { + const [timerCount, setTimerCount] = useState(INITIAL_TIMER); + const [barWidth, setBarWidth] = useState(INITIAL_WIDTH); + const isAlmostFinished = timerCount <= 5; + + const timeout = useRef(); + + useEffect(() => { + if (timerCount <= 0) { + clearInterval(timeout.current); + } + }, [timerCount]); + + useEffect(() => { + timeout.current = setInterval(() => { + setTimerCount((prev) => prev - 1); + setBarWidth((prevWidth) => (prevWidth > 0 ? prevWidth - INITIAL_WIDTH / INITIAL_TIMER : 0)); + }, 1000); + + return () => { + clearInterval(timeout.current); + }; + }, []); + + return { timerCount, barWidth, isAlmostFinished }; +}; + +export { useRoundTimer }; diff --git a/frontend/src/components/Timer/Timer.tsx b/frontend/src/components/Timer/Timer.tsx index f621d215..893298a8 100644 --- a/frontend/src/components/Timer/Timer.tsx +++ b/frontend/src/components/Timer/Timer.tsx @@ -1,5 +1,4 @@ -import { useEffect, useRef, useState } from 'react'; - +import { useRoundTimer } from './Timer.hook'; import { timerIcon, timerIconShake, @@ -12,49 +11,23 @@ import { formatTimer } from './Timer.util'; import HOME_ICON from '@/assets/images/homeIcon.svg'; -const INITIAL_TIMER = 30; -const INITIAL_WIDTH = 100; - const Timer = () => { - const [timer, setTimer] = useState(INITIAL_TIMER); - const [width, setWidth] = useState(INITIAL_WIDTH); - const isAlmostFinished = timer <= 5; - - const timeout = useRef(); - - useEffect(() => { - if (timer <= 0) { - clearInterval(timeout.current); - } - }, [timer]); - - useEffect(() => { - timeout.current = setInterval(() => { - setTimer((prev) => prev - 1); - setWidth((prevWidth) => (prevWidth > 0 ? prevWidth - INITIAL_WIDTH / INITIAL_TIMER : 0)); - }, 1000); - - return () => { - clearInterval(timeout.current); - }; - }, []); + const { barWidth, timerCount, isAlmostFinished } = useRoundTimer(); return ( - <> -
    -
    -
    - 타이머 - {formatTimer(timer)} -
    +
    +
    +
    + 타이머 + {formatTimer(timerCount)}
    - +
    ); }; diff --git a/frontend/src/pages/GamePage/GamePage.tsx b/frontend/src/pages/GamePage/GamePage.tsx index 15abde60..5fdf4439 100644 --- a/frontend/src/pages/GamePage/GamePage.tsx +++ b/frontend/src/pages/GamePage/GamePage.tsx @@ -5,13 +5,11 @@ import TopicContainer from '@/components/TopicContainer/TopicContainer'; const GamePage = () => { return ( - <> - - - - - - + + + + + ); }; From e078e877e39eba4bcdce81071803c6b498083589 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Fri, 2 Aug 2024 00:20:25 +0900 Subject: [PATCH 0428/1013] =?UTF-8?q?refactor:=20=ED=99=94=EC=82=B4=20?= =?UTF-8?q?=EA=B8=B0=ED=98=B8=20=EB=B0=A9=ED=96=A5=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?#93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/main/java/ddangkong/domain/balance/room/Room.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/Room.java b/backend/src/main/java/ddangkong/domain/balance/room/Room.java index 32b1aa48..c4663f22 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/Room.java @@ -82,7 +82,7 @@ private void validateGreaterThanOrEqualToStartRound(int round) { } private void validateLessThanOrEqualToCurrentRound(int round) { - if (currentRound < round) { + if (round > currentRound) { throw new BadRequestException("currentRound보다 작거나 같아야 합니다. currentRound : %d, round : %d" .formatted(currentRound, round) ); From 48c4262116d0b1609205fc8763efedf33a610d4e Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Fri, 2 Aug 2024 00:20:52 +0900 Subject: [PATCH 0429/1013] =?UTF-8?q?refactor:=20=EB=B3=80=EC=88=98?= =?UTF-8?q?=EB=AA=85=20actual=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20#93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/balance/room/RoomControllerTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java index ee464d36..e8263456 100644 --- a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java @@ -159,7 +159,7 @@ class 나의_라운드_종료_여부 { @Test void 나의_라운드가_종료되었는지_조회한다() { // when - RoundFinishedResponse roundFinishedResponse = RestAssured.given().log().all() + RoundFinishedResponse actual = RestAssured.given().log().all() .pathParam("roomId", 1L) .queryParam("myRound", 1) .when().get("/api/balances/rooms/{roomId}/round-finished") @@ -169,8 +169,8 @@ class 나의_라운드_종료_여부 { // then assertAll( - () -> assertThat(roundFinishedResponse.isRoundFinished()).isTrue(), - () -> assertThat(roundFinishedResponse.isGameFinished()).isFalse() + () -> assertThat(actual.isRoundFinished()).isTrue(), + () -> assertThat(actual.isGameFinished()).isFalse() ); } } From 2a122656f16a18771dfee25f4f8c2e3b891f1adb Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Fri, 2 Aug 2024 00:22:33 +0900 Subject: [PATCH 0430/1013] =?UTF-8?q?refactor:=20prefix=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20#93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/balance/room/RoomTest.java | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java index 6da1f7b6..a9a47301 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java @@ -14,7 +14,6 @@ class RoomTest { @Nested class 다음_라운드로_이동 { - @Test void 다음_라운드로_이동할_수_있다() { // given @@ -47,15 +46,15 @@ class 다음_라운드로_이동 { @Nested class 라운드_종료 { - private static final int FIXED_TOTAL_ROUND = 5; - private static final int FIXED_TIME_LIMIT = 30; - private static final RoomStatus FIXED_STATUS = RoomStatus.PROGRESS; + private static final int TOTAL_ROUND = 5; + private static final int TIME_LIMIT = 30; + private static final RoomStatus STATUS = RoomStatus.PROGRESS; @Test void 나의_라운드가_방의_현재_라운드보다_작으면_나의_라운드는_종료된_것이다() { // given int currentRound = 2; - Room room = new Room(FIXED_TOTAL_ROUND, currentRound, FIXED_TIME_LIMIT, FIXED_STATUS); + Room room = new Room(TOTAL_ROUND, currentRound, TIME_LIMIT, STATUS); int myRound = 1; // when @@ -69,7 +68,7 @@ class 라운드_종료 { void 나의_라운드와_방의_현재_라운드와_같으면_나의_라운드는_종료되지_않은_것이다() { // given int currentRound = 2; - Room room = new Room(FIXED_TOTAL_ROUND, currentRound, FIXED_TIME_LIMIT, FIXED_STATUS); + Room room = new Room(TOTAL_ROUND, currentRound, TIME_LIMIT, STATUS); int myRound = 2; // when @@ -82,7 +81,7 @@ class 라운드_종료 { @Test void 나의_라운드가_방의_시작_라운드보다_작으면_예외가_발생한다() { // given - Room room = new Room(FIXED_TOTAL_ROUND, 1, FIXED_TIME_LIMIT, FIXED_STATUS); + Room room = new Room(TOTAL_ROUND, 1, TIME_LIMIT, STATUS); int invalidMyRound = 0; // when & then @@ -95,7 +94,7 @@ class 라운드_종료 { void 나의_라운드가_방의_현재_라운드보다_크면_예외가_발생한다() { // given int currentRound = 1; - Room room = new Room(FIXED_TOTAL_ROUND, currentRound, FIXED_TIME_LIMIT, FIXED_STATUS); + Room room = new Room(TOTAL_ROUND, currentRound, TIME_LIMIT, STATUS); int invalidMyRound = 2; // when & then @@ -108,7 +107,7 @@ class 라운드_종료 { void 나의_라운드가_방의_현재_라운드보다_2이상_작으면_예외가_발생한다() { // given int currentRound = 4; - Room room = new Room(FIXED_TOTAL_ROUND, currentRound, FIXED_TIME_LIMIT, FIXED_STATUS); + Room room = new Room(TOTAL_ROUND, currentRound, TIME_LIMIT, STATUS); int invalidMyRound = 2; // when & then @@ -121,7 +120,7 @@ class 라운드_종료 { void 현재_라운드와_전체_라운드가_같고_방_상태가_FINISH이면_방의_전체_라운드가_종료된_것이다() { // given RoomStatus status = RoomStatus.FINISH; - Room room = new Room(FIXED_TOTAL_ROUND, 5, FIXED_TIME_LIMIT, status); + Room room = new Room(TOTAL_ROUND, 5, TIME_LIMIT, status); // when boolean actual = room.isAllRoundFinished(); @@ -135,7 +134,7 @@ class 라운드_종료 { // given int currentRound = 3; int totalRound = 5; - Room room = new Room(totalRound, currentRound, FIXED_TIME_LIMIT, FIXED_STATUS); + Room room = new Room(totalRound, currentRound, TIME_LIMIT, STATUS); // when boolean actual = room.isAllRoundFinished(); @@ -148,7 +147,7 @@ class 라운드_종료 { @EnumSource(value = RoomStatus.class, names = {"READY", "PROGRESS"}) void 방_상태가_FINISH가_아니면_방의_전체_라운드가_종료되지_않은_것이다(RoomStatus status) { // given - Room room = new Room(FIXED_TOTAL_ROUND, 5, FIXED_TIME_LIMIT, status); + Room room = new Room(TOTAL_ROUND, 5, TIME_LIMIT, status); // when boolean actual = room.isAllRoundFinished(); From dede05833006f187459957328dad651644a315c2 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Fri, 2 Aug 2024 00:24:18 +0900 Subject: [PATCH 0431/1013] =?UTF-8?q?refactor:=20when,=20then=20=ED=95=9C?= =?UTF-8?q?=20=EC=A4=84=EB=A1=9C=20=ED=86=B5=ED=95=A9=20#93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/balance/room/RoomTest.java | 35 ++++++------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java index a9a47301..4a5864cd 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java @@ -57,11 +57,8 @@ class 라운드_종료 { Room room = new Room(TOTAL_ROUND, currentRound, TIME_LIMIT, STATUS); int myRound = 1; - // when - boolean actual = room.isMyRoundFinished(myRound); - - // then - assertThat(actual).isTrue(); + // when & then + assertThat(room.isMyRoundFinished(myRound)).isTrue(); } @Test @@ -71,11 +68,8 @@ class 라운드_종료 { Room room = new Room(TOTAL_ROUND, currentRound, TIME_LIMIT, STATUS); int myRound = 2; - // when - boolean actual = room.isMyRoundFinished(myRound); - - // then - assertThat(actual).isFalse(); + // when & then + assertThat(room.isMyRoundFinished(myRound)).isFalse(); } @Test @@ -122,11 +116,8 @@ class 라운드_종료 { RoomStatus status = RoomStatus.FINISH; Room room = new Room(TOTAL_ROUND, 5, TIME_LIMIT, status); - // when - boolean actual = room.isAllRoundFinished(); - - // then - assertThat(actual).isTrue(); + // when & then + assertThat(room.isAllRoundFinished()).isTrue(); } @Test @@ -136,11 +127,8 @@ class 라운드_종료 { int totalRound = 5; Room room = new Room(totalRound, currentRound, TIME_LIMIT, STATUS); - // when - boolean actual = room.isAllRoundFinished(); - - // then - assertThat(actual).isFalse(); + // when & then + assertThat(room.isAllRoundFinished()).isFalse(); } @ParameterizedTest @@ -149,11 +137,8 @@ class 라운드_종료 { // given Room room = new Room(TOTAL_ROUND, 5, TIME_LIMIT, status); - // when - boolean actual = room.isAllRoundFinished(); - - // then - assertThat(actual).isFalse(); + // when & then + assertThat(room.isAllRoundFinished()).isFalse(); } } } From 67abce011708a83a9350a0ac579234d7f1959518 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Fri, 2 Aug 2024 00:35:26 +0900 Subject: [PATCH 0432/1013] =?UTF-8?q?refactor:=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=EB=AA=85=20=EB=B3=80=EA=B2=BD=20#93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ddangkong/service/balance/room/RoomServiceTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java index 641a255f..4276552a 100644 --- a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java @@ -144,7 +144,7 @@ class 나의_라운드_종료_여부 { private static final RoomStatus FIXED_STATUS = RoomStatus.PROGRESS; @Test - void 나의_라운드가_종료되지_않았으면_게임도_종료되지_않은_상태이다() { + void 나의_라운드가_종료되지_않았으면_게임도_종료되지_않은_상태여야_한다() { // given int currentRound = 2; Room room = roomRepository.save(new Room(FIXED_TOTAL_ROUND, currentRound, FIXED_TIME_LIMIT, FIXED_STATUS)); @@ -161,7 +161,7 @@ class 나의_라운드_종료_여부 { } @Test - void 나의_라운드가_종료되면_게임은_종료되지_않은_상태이다() { + void 나의_라운드가_종료되면_게임은_종료되지_않은_상태여야_한다() { // given int currentRound = 2; Room room = roomRepository.save(new Room(FIXED_TOTAL_ROUND, currentRound, FIXED_TIME_LIMIT, FIXED_STATUS)); @@ -178,7 +178,7 @@ class 나의_라운드_종료_여부 { } @Test - void 게임이_종료되면_나의_라운드는_종료되지_않은_상태이다() { + void 게임이_종료되면_나의_라운드는_종료되지_않은_상태여야_한다() { // given int currentRound = 5; RoomStatus status = RoomStatus.FINISH; @@ -196,7 +196,7 @@ class 나의_라운드_종료_여부 { } @Test - void 현재_마지막_라운드여도_게임이_종료되지_않은_상태이면_나의_라운드도_종료되지_않은_상태이다() { + void 현재_마지막_라운드여도_게임이_종료되지_않은_상태이면_나의_라운드도_종료되지_않은_상태여야_한다() { // given int currentRound = 5; Room room = roomRepository.save(new Room(FIXED_TOTAL_ROUND, currentRound, FIXED_TIME_LIMIT, FIXED_STATUS)); From 9f6bb0e1140bcb91fd1e83701660831a6802b973 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Fri, 2 Aug 2024 00:38:22 +0900 Subject: [PATCH 0433/1013] =?UTF-8?q?feat:=20=EC=84=9C=EB=B2=84=EC=97=90?= =?UTF-8?q?=EC=84=9C=20timeLimit=EC=9D=84=20=EB=B0=9B=EC=95=84=20=ED=83=80?= =?UTF-8?q?=EC=9D=B4=EB=A8=B8=20=EC=84=A4=EC=A0=95=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/Timer/Timer.hook.ts | 20 +++++++++++++++----- frontend/src/mocks/data/balanceContent.json | 5 +++-- frontend/src/types/balanceContent.ts | 1 + 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/Timer/Timer.hook.ts b/frontend/src/components/Timer/Timer.hook.ts index 0b1f7515..e3393c75 100644 --- a/frontend/src/components/Timer/Timer.hook.ts +++ b/frontend/src/components/Timer/Timer.hook.ts @@ -1,10 +1,15 @@ import { useEffect, useRef, useState } from 'react'; -const INITIAL_TIMER = 30; // TODO: tanstack-query로 timeLimit 서버 데이터 받아오기 +import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; + const INITIAL_WIDTH = 100; +const DELAY = 1000; const useRoundTimer = () => { - const [timerCount, setTimerCount] = useState(INITIAL_TIMER); + const { balanceContent } = useBalanceContentQuery(); + const timeLimit = balanceContent?.timeLimit || 30; + + const [timerCount, setTimerCount] = useState(timeLimit); const [barWidth, setBarWidth] = useState(INITIAL_WIDTH); const isAlmostFinished = timerCount <= 5; @@ -17,15 +22,20 @@ const useRoundTimer = () => { }, [timerCount]); useEffect(() => { + if (!balanceContent) return; + + const DECREASE_RATE = INITIAL_WIDTH / timeLimit; + setTimerCount(timeLimit); + timeout.current = setInterval(() => { setTimerCount((prev) => prev - 1); - setBarWidth((prevWidth) => (prevWidth > 0 ? prevWidth - INITIAL_WIDTH / INITIAL_TIMER : 0)); - }, 1000); + setBarWidth((prevWidth) => (prevWidth > 0 ? prevWidth - DECREASE_RATE : 0)); + }, DELAY); return () => { clearInterval(timeout.current); }; - }, []); + }, [balanceContent, timeLimit]); return { timerCount, barWidth, isAlmostFinished }; }; diff --git a/frontend/src/mocks/data/balanceContent.json b/frontend/src/mocks/data/balanceContent.json index 8fec9067..2440e234 100644 --- a/frontend/src/mocks/data/balanceContent.json +++ b/frontend/src/mocks/data/balanceContent.json @@ -1,9 +1,10 @@ { - "totalRound": 5, - "currentRound": 1, "contentId": 1, "category": "연애", "question": "당신의 결혼 상대는?", + "timeLimit": 15, + "totalRound": 5, + "currentRound": 1, "firstOption": { "optionId": 1, "name": "100억 빚 송강" diff --git a/frontend/src/types/balanceContent.ts b/frontend/src/types/balanceContent.ts index 71ea8ddf..17f93225 100644 --- a/frontend/src/types/balanceContent.ts +++ b/frontend/src/types/balanceContent.ts @@ -2,6 +2,7 @@ export interface BalanceContent { contentId: number; category: string; question: string; + timeLimit: number; totalRound: number; currentRound: number; firstOption: { From 60d30b9cdd3a256943e4c6b2c935277155c5edb3 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Fri, 2 Aug 2024 00:41:58 +0900 Subject: [PATCH 0434/1013] =?UTF-8?q?refactor:=20Room=20validation=20?= =?UTF-8?q?=ED=86=B5=ED=95=A9=20#93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ddangkong/domain/balance/room/Room.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/Room.java b/backend/src/main/java/ddangkong/domain/balance/room/Room.java index c4663f22..557eec3e 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/Room.java @@ -67,29 +67,21 @@ public boolean isGameProgress() { } public boolean isMyRoundFinished(int myRound) { - validateGreaterThanOrEqualToStartRound(myRound); - validateLessThanOrEqualToCurrentRound(myRound); - validateDifferenceBetweenRoundAndCurrentRound(myRound); + validateRound(myRound); return currentRound != myRound; } - private void validateGreaterThanOrEqualToStartRound(int round) { + private void validateRound(int round) { if (round < START_ROUND) { throw new BadRequestException("startRound보다 크거나 같아야 합니다. startRound : %d, round : %d" .formatted(START_ROUND, round) ); } - } - - private void validateLessThanOrEqualToCurrentRound(int round) { if (round > currentRound) { throw new BadRequestException("currentRound보다 작거나 같아야 합니다. currentRound : %d, round : %d" .formatted(currentRound, round) ); } - } - - private void validateDifferenceBetweenRoundAndCurrentRound(int round) { if (round < currentRound && currentRound - round != 1) { throw new BadRequestException("currentRound과 round의 차이는 %d이하여야 합니다. currentRound : %d, round : %d" .formatted(ALLOWED_ROUND_GAP, currentRound, round) From 2338538817a2232f9fe2e42079c90b7795aeac37 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Fri, 2 Aug 2024 00:45:29 +0900 Subject: [PATCH 0435/1013] =?UTF-8?q?refactor:=20EnumSource=20mode=20exclu?= =?UTF-8?q?de=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20#93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/test/java/ddangkong/domain/balance/room/RoomTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java index 4a5864cd..c95deb5a 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java @@ -8,6 +8,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.EnumSource.Mode; class RoomTest { @@ -132,7 +133,7 @@ class 라운드_종료 { } @ParameterizedTest - @EnumSource(value = RoomStatus.class, names = {"READY", "PROGRESS"}) + @EnumSource(mode = Mode.EXCLUDE, names = {"FINISH"}) void 방_상태가_FINISH가_아니면_방의_전체_라운드가_종료되지_않은_것이다(RoomStatus status) { // given Room room = new Room(TOTAL_ROUND, 5, TIME_LIMIT, status); From c24011c0cdb653eb305e983b676494159fc7a454 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Fri, 2 Aug 2024 01:21:54 +0900 Subject: [PATCH 0436/1013] =?UTF-8?q?refactor:=20prefix=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20#93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/balance/room/RoomServiceTest.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java index 4276552a..ce13809b 100644 --- a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java @@ -139,15 +139,15 @@ class 다음_라운드로_이동 { @Nested class 나의_라운드_종료_여부 { - private static final int FIXED_TOTAL_ROUND = 5; - private static final int FIXED_TIME_LIMIT = 30_000; - private static final RoomStatus FIXED_STATUS = RoomStatus.PROGRESS; + private static final int TOTAL_ROUND = 5; + private static final int TIME_LIMIT = 30_000; + private static final RoomStatus STATUS = RoomStatus.PROGRESS; @Test void 나의_라운드가_종료되지_않았으면_게임도_종료되지_않은_상태여야_한다() { // given int currentRound = 2; - Room room = roomRepository.save(new Room(FIXED_TOTAL_ROUND, currentRound, FIXED_TIME_LIMIT, FIXED_STATUS)); + Room room = roomRepository.save(new Room(TOTAL_ROUND, currentRound, TIME_LIMIT, STATUS)); int myRound = 2; // when @@ -164,7 +164,7 @@ class 나의_라운드_종료_여부 { void 나의_라운드가_종료되면_게임은_종료되지_않은_상태여야_한다() { // given int currentRound = 2; - Room room = roomRepository.save(new Room(FIXED_TOTAL_ROUND, currentRound, FIXED_TIME_LIMIT, FIXED_STATUS)); + Room room = roomRepository.save(new Room(TOTAL_ROUND, currentRound, TIME_LIMIT, STATUS)); int myRound = 1; // when @@ -182,7 +182,7 @@ class 나의_라운드_종료_여부 { // given int currentRound = 5; RoomStatus status = RoomStatus.FINISH; - Room room = roomRepository.save(new Room(FIXED_TOTAL_ROUND, currentRound, FIXED_TIME_LIMIT, status)); + Room room = roomRepository.save(new Room(TOTAL_ROUND, currentRound, TIME_LIMIT, status)); int myRound = 5; // when @@ -199,7 +199,7 @@ class 나의_라운드_종료_여부 { void 현재_마지막_라운드여도_게임이_종료되지_않은_상태이면_나의_라운드도_종료되지_않은_상태여야_한다() { // given int currentRound = 5; - Room room = roomRepository.save(new Room(FIXED_TOTAL_ROUND, currentRound, FIXED_TIME_LIMIT, FIXED_STATUS)); + Room room = roomRepository.save(new Room(TOTAL_ROUND, currentRound, TIME_LIMIT, STATUS)); int myRound = 5; // when From 55fa257d1a3aa68b8cd70678a5704d6d65911c9f Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Fri, 2 Aug 2024 01:48:00 +0900 Subject: [PATCH 0437/1013] =?UTF-8?q?refactor:=20=EB=A7=A4=EC=A7=81?= =?UTF-8?q?=EB=84=98=EB=B2=84=20=EC=83=81=EC=88=98=ED=99=94=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=20#93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/main/java/ddangkong/domain/balance/room/Room.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/Room.java b/backend/src/main/java/ddangkong/domain/balance/room/Room.java index 557eec3e..981a086d 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/Room.java @@ -82,7 +82,7 @@ private void validateRound(int round) { .formatted(currentRound, round) ); } - if (round < currentRound && currentRound - round != 1) { + if (round < currentRound && currentRound - round != ALLOWED_ROUND_GAP) { throw new BadRequestException("currentRound과 round의 차이는 %d이하여야 합니다. currentRound : %d, round : %d" .formatted(ALLOWED_ROUND_GAP, currentRound, round) ); From dc845c085ffa40680839f75305361eb07bca5438 Mon Sep 17 00:00:00 2001 From: jhon3242 Date: Thu, 1 Aug 2024 16:35:08 +0900 Subject: [PATCH 0438/1013] =?UTF-8?q?feat:=20=ED=88=AC=ED=91=9C=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC=20=EB=B0=8F=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20#96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ddangkong/config/ClockConfig.java | 15 +++++++ .../domain/balance/room/RoomContent.java | 15 +++++-- .../balance/vote/BalanceVoteService.java | 15 +++++-- .../vote/BalanceVoteControllerTest.java | 5 ++- .../balance/vote/BalanceVoteServiceTest.java | 39 +++++++++++++++++-- .../support/config/TestClockConfig.java | 26 +++++++++++++ backend/src/test/resources/init-test.sql | 10 ++--- 7 files changed, 109 insertions(+), 16 deletions(-) create mode 100644 backend/src/main/java/ddangkong/config/ClockConfig.java create mode 100644 backend/src/test/java/ddangkong/support/config/TestClockConfig.java diff --git a/backend/src/main/java/ddangkong/config/ClockConfig.java b/backend/src/main/java/ddangkong/config/ClockConfig.java new file mode 100644 index 00000000..d4fa7b9f --- /dev/null +++ b/backend/src/main/java/ddangkong/config/ClockConfig.java @@ -0,0 +1,15 @@ +package ddangkong.config; + +import java.time.Clock; +import java.time.ZoneId; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ClockConfig { + + @Bean + public Clock clock() { + return Clock.system(ZoneId.of("Asia/Seoul")); + } +} diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java index 66caf260..07af31a6 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java @@ -3,6 +3,7 @@ import ddangkong.domain.BaseEntity; import ddangkong.domain.balance.content.BalanceContent; import ddangkong.domain.balance.content.Category; +import ddangkong.exception.BadRequestException; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; @@ -15,7 +16,6 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; -import org.springframework.data.annotation.CreatedDate; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -37,11 +37,13 @@ public class RoomContent extends BaseEntity { @Column(nullable = false) private int round; - @Column(nullable = false) private LocalDateTime roundEndedAt; + @Column(nullable = false) + private boolean isUsed; + public boolean isRoundOver(LocalDateTime currentTime) { - return roundEndedAt.isAfter(currentTime); + return currentTime.isAfter(getRoundEndedAt()); } public Long getContentId() { @@ -59,4 +61,11 @@ public String getContentName() { public int getTotalRound() { return room.getTotalRound(); } + + public LocalDateTime getRoundEndedAt() { + if (roundEndedAt == null) { + throw new BadRequestException("라운드 종료 시간이 설정되지 않습니다."); + } + return roundEndedAt; + } } diff --git a/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java b/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java index aec899af..f986de4c 100644 --- a/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java +++ b/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java @@ -19,6 +19,7 @@ import ddangkong.domain.member.Member; import ddangkong.domain.member.MemberRepository; import ddangkong.exception.BadRequestException; +import java.time.Clock; import java.time.LocalDateTime; import java.util.List; import java.util.Objects; @@ -42,9 +43,11 @@ public class BalanceVoteService { private final RoomRepository roomRepository; + private final Clock clock; + @Transactional public BalanceVoteResponse createBalanceVote(BalanceVoteRequest request, Long roomId, Long contentId) { - validateVoteTime(roomId); + validateRoundEnded(roomId, contentId); BalanceOption balanceOption = findValidOption(request.optionId(), contentId); Member member = findValidMember(request.memberId(), roomId); @@ -53,13 +56,17 @@ public BalanceVoteResponse createBalanceVote(BalanceVoteRequest request, Long ro return new BalanceVoteResponse(savedBalanceVote); } - private void validateVoteTime(Long roomId) { + private void validateRoundEnded(Long roomId, Long contentId) { RoomContent roomContent = findValidRoomContent(roomId); - if (roomContent.isRoundOver(LocalDateTime.now())) { - throw new BadRequestException("이미 종료된 라운드는 투표할 수 없습니다."); + if (isNotCurrentContentId(contentId, roomContent) || roomContent.isRoundOver(LocalDateTime.now(clock))) { + throw new BadRequestException("유효하지 않은 라운드에는 투표할 수 없습니다."); } } + private static boolean isNotCurrentContentId(Long contentId, RoomContent roomContent) { + return !Objects.equals(roomContent.getContentId(), contentId); + } + private RoomContent findValidRoomContent(Long roomId) { Room room = roomRepository.getById(roomId); return roomContentRepository.findByRoomAndRound(room, room.getCurrentRound()) diff --git a/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java index c342465a..5a69fbdc 100644 --- a/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java @@ -5,11 +5,14 @@ import ddangkong.controller.BaseControllerTest; import ddangkong.controller.balance.vote.dto.BalanceVoteRequest; import ddangkong.controller.balance.vote.dto.BalanceVoteResponse; +import ddangkong.support.config.TestClockConfig; import io.restassured.RestAssured; import io.restassured.http.ContentType; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; +@Import(TestClockConfig.class) class BalanceVoteControllerTest extends BaseControllerTest { @Nested @@ -21,7 +24,7 @@ class 투표_생성 { private static final BalanceVoteResponse EXPECTED_RESPONSE = new BalanceVoteResponse(1L); @Test - void 현재_방의_질문을_조회할_수_있다() { + void 현재_방에서_투표할_수_있다() { // given & when BalanceVoteResponse actual = RestAssured.given().log().all() .body(NORMAL_REQUEST).contentType(ContentType.JSON) diff --git a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java index af1f1d13..06c60e96 100644 --- a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java @@ -12,11 +12,14 @@ import ddangkong.controller.balance.vote.dto.BalanceVoteResultResponse; import ddangkong.exception.BadRequestException; import ddangkong.service.BaseServiceTest; +import ddangkong.support.config.TestClockConfig; import java.util.List; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Import; +@Import(TestClockConfig.class) class BalanceVoteServiceTest extends BaseServiceTest { @Autowired @@ -45,8 +48,8 @@ class 투표_생성 { @Test void 질문에_해당하는_선택지가_아닌_경우_예외를_던진다() { // given - Long optionId = 1L; - Long contentId = 2L; + Long optionId = 3L; + Long contentId = 1L; Long memberId = 1L; Long roomId = 1L; @@ -63,7 +66,7 @@ class 투표_생성 { Long optionId = 1L; Long contentId = 1L; Long memberId = 1L; - Long roomId = 2L; + Long roomId = 3L; // when & then assertThatThrownBy(() -> balanceVoteService.createBalanceVote( @@ -71,6 +74,36 @@ class 투표_생성 { .isInstanceOf(BadRequestException.class) .hasMessage("해당 방의 멤버가 존재하지 않습니다."); } + + @Test + void 투표_시간이_지난_이후_투표_시_예외를_던진다() { + // given + Long optionId = 3L; + Long contentId = 2L; + Long memberId = 1L; + Long roomId = 1L; + + // when & then + assertThatThrownBy(() -> balanceVoteService.createBalanceVote( + new BalanceVoteRequest(memberId, optionId), roomId, contentId)) + .isInstanceOf(BadRequestException.class) + .hasMessage("유효하지 않은 라운드에는 투표할 수 없습니다."); + } + + @Test + void 아직_진행하지_않은_컨텐츠에_투표_시_예외를_던진다() { + // given + Long optionId = 5L; + Long contentId = 3L; + Long memberId = 1L; + Long roomId = 1L; + + // when & then + assertThatThrownBy(() -> balanceVoteService.createBalanceVote( + new BalanceVoteRequest(memberId, optionId), roomId, contentId)) + .isInstanceOf(BadRequestException.class) + .hasMessage("유효하지 않은 라운드에는 투표할 수 없습니다."); + } } @Nested diff --git a/backend/src/test/java/ddangkong/support/config/TestClockConfig.java b/backend/src/test/java/ddangkong/support/config/TestClockConfig.java new file mode 100644 index 00000000..ec1cb1dd --- /dev/null +++ b/backend/src/test/java/ddangkong/support/config/TestClockConfig.java @@ -0,0 +1,26 @@ +package ddangkong.support.config; + +import java.time.Clock; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; + +@TestConfiguration +public class TestClockConfig { + + @Primary + @Bean + public Clock testClock() { + String dateTimeString = "2024-07-18 20:00:02.000"; + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); + LocalDateTime customDateTime = LocalDateTime.parse(dateTimeString, formatter); + ZonedDateTime customZonedDateTime = customDateTime.atZone(ZoneId.of("Asia/Seoul")); + Instant customInstant = customZonedDateTime.toInstant(); + return Clock.fixed(customInstant, ZoneId.of("Asia/Seoul")); + } +} diff --git a/backend/src/test/resources/init-test.sql b/backend/src/test/resources/init-test.sql index a28b7140..9f9b6c29 100644 --- a/backend/src/test/resources/init-test.sql +++ b/backend/src/test/resources/init-test.sql @@ -16,11 +16,11 @@ VALUES ('EXAMPLE', '민초 vs 반민초'), ('EXAMPLE', '월 200 백수 vs 월 500 직장인'), ('EXAMPLE', '다음 중 여행가고 싶은 곳은?'); -INSERT INTO room_content (room_id, balance_content_id, round, created_at, round_ended_at) -VALUES (1, 2, 1, '2024-07-18 19:50:00.000', '2099-12-31 23:59:59.999'), - (1, 1, 2, '2024-07-18 20:00:00.000', '2099-12-31 23:59:59.999'), - (1, 3, 3, '2024-07-18 20:00:00.000', '2099-12-31 23:59:59.999'), - (3, 1, 1, '2024-07-18 19:51:00.000', '2099-12-31 23:59:59.999'); +INSERT INTO room_content (room_id, balance_content_id, round, created_at, round_ended_at, is_used) +VALUES (1, 2, 1, '2024-07-18 19:50:00.000', '2024-07-18 19:50:32.000', false), + (1, 1, 2, '2024-07-18 19:50:00.000', '2024-07-18 20:00:32.000', false), + (1, 3, 3, '2024-07-18 19:50:00.000', null, false), + (3, 1, 1, '2024-07-18 20:00:00.000', '2024-07-18 20:00:32.000', false); INSERT INTO balance_option (name, balance_content_id) VALUES ('민초', 1), From 287e56b4e1aa0243b95748a182de3a87fd427a06 Mon Sep 17 00:00:00 2001 From: jhon3242 Date: Fri, 2 Aug 2024 13:55:31 +0900 Subject: [PATCH 0439/1013] =?UTF-8?q?refactor:=20=EA=B0=9D=EC=B2=B4?= =?UTF-8?q?=EC=97=90=EA=B2=8C=20=EB=A9=94=EC=8B=9C=EC=A7=80=EB=A5=BC=20?= =?UTF-8?q?=EB=AC=BB=EB=8A=94=20=EB=B0=A9=EC=8B=9D=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=84=B0=EB=A7=81=20#96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ddangkong/domain/balance/room/RoomContent.java | 5 +++++ .../ddangkong/service/balance/vote/BalanceVoteService.java | 6 +----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java index 07af31a6..78f3d712 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java @@ -13,6 +13,7 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import java.time.LocalDateTime; +import java.util.Objects; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -46,6 +47,10 @@ public boolean isRoundOver(LocalDateTime currentTime) { return currentTime.isAfter(getRoundEndedAt()); } + public boolean isNotSameContentId(Long contentId) { + return !Objects.equals(getContentId(), contentId); + } + public Long getContentId() { return balanceContent.getId(); } diff --git a/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java b/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java index f986de4c..dbef7bb6 100644 --- a/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java +++ b/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java @@ -58,15 +58,11 @@ public BalanceVoteResponse createBalanceVote(BalanceVoteRequest request, Long ro private void validateRoundEnded(Long roomId, Long contentId) { RoomContent roomContent = findValidRoomContent(roomId); - if (isNotCurrentContentId(contentId, roomContent) || roomContent.isRoundOver(LocalDateTime.now(clock))) { + if (roomContent.isNotSameContentId(contentId) || roomContent.isRoundOver(LocalDateTime.now(clock))) { throw new BadRequestException("유효하지 않은 라운드에는 투표할 수 없습니다."); } } - private static boolean isNotCurrentContentId(Long contentId, RoomContent roomContent) { - return !Objects.equals(roomContent.getContentId(), contentId); - } - private RoomContent findValidRoomContent(Long roomId) { Room room = roomRepository.getById(roomId); return roomContentRepository.findByRoomAndRound(room, room.getCurrentRound()) From 33e70cb58fb493a862c519dc420a3c561b4f8d85 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 1 Aug 2024 20:33:58 +0900 Subject: [PATCH 0440/1013] =?UTF-8?q?feat:=20Room=20Entity=EC=97=90=20Cate?= =?UTF-8?q?gory=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80=20#107?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ddangkong/domain/balance/room/Room.java | 18 ++++++++++++++++-- backend/src/main/resources/sql/data-dev.sql | 4 ++-- .../domain/balance/room/RoomTest.java | 3 ++- backend/src/test/resources/init-test.sql | 8 ++++---- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/Room.java b/backend/src/main/java/ddangkong/domain/balance/room/Room.java index 90c4bf9d..a5b516b4 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/Room.java @@ -1,5 +1,6 @@ package ddangkong.domain.balance.room; +import ddangkong.domain.balance.content.Category; import ddangkong.exception.BadRequestException; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -38,15 +39,20 @@ public class Room { @Enumerated(EnumType.STRING) private RoomStatus status; + @Column(nullable = false) + @Enumerated(EnumType.STRING) + private Category category; + public static Room createNewRoom() { - return new Room(DEFAULT_TOTAL_ROUND, START_ROUND, DEFAULT_TIME_LIMIT_MSEC, RoomStatus.READY); + return new Room(DEFAULT_TOTAL_ROUND, START_ROUND, DEFAULT_TIME_LIMIT_MSEC, RoomStatus.READY, Category.EXAMPLE); } - public Room(int totalRound, int currentRound, int timeLimit, RoomStatus status) { + public Room(int totalRound, int currentRound, int timeLimit, RoomStatus status, Category category) { this.totalRound = totalRound; this.currentRound = currentRound; this.timeLimit = timeLimit; this.status = status; + this.category = category; } public void moveToNextRound() { @@ -57,6 +63,14 @@ public void moveToNextRound() { throw new BadRequestException("마지막 라운드입니다."); } + public void updateTimeLimit(int timeLimit) { + this.timeLimit = timeLimit; + } + + public void updateTotalRound(int totalRound) { + this.totalRound = totalRound; + } + private boolean canMoveToNextRound() { return currentRound < totalRound; } diff --git a/backend/src/main/resources/sql/data-dev.sql b/backend/src/main/resources/sql/data-dev.sql index c11a759a..aefdf3c2 100644 --- a/backend/src/main/resources/sql/data-dev.sql +++ b/backend/src/main/resources/sql/data-dev.sql @@ -19,8 +19,8 @@ VALUES ('민초', 1), ('어떻게 죽을 지 알기', 5); -INSERT INTO room(total_round, current_round, time_limit, status) -VALUES (5, 1, 30000, 'READY'); +INSERT INTO room(total_round, current_round, time_limit, status, category) +VALUES (5, 1, 30000, 'READY', 'EXAMPLE'); INSERT INTO room_content(room_id, balance_content_id, round, created_at) diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java index 2cde8032..c5bf6d9e 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java @@ -3,6 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import ddangkong.domain.balance.content.Category; import ddangkong.exception.BadRequestException; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -33,7 +34,7 @@ class 다음_라운드로_이동 { int totalRound = 5; int currentRound = 5; int timeLimit = 30000; - Room room = new Room(totalRound, currentRound, timeLimit, RoomStatus.PROGRESS); + Room room = new Room(totalRound, currentRound, timeLimit, RoomStatus.PROGRESS, Category.EXAMPLE); // when & then assertThatThrownBy(room::moveToNextRound) diff --git a/backend/src/test/resources/init-test.sql b/backend/src/test/resources/init-test.sql index f874c45a..39b7dfe2 100644 --- a/backend/src/test/resources/init-test.sql +++ b/backend/src/test/resources/init-test.sql @@ -1,7 +1,7 @@ -INSERT INTO room (total_round, current_round, time_limit, status) -VALUES (5, 2, 30000, 'PROGRESS'), - (5, 1, 30000, 'PROGRESS'), - (5, 1, 30000, 'PROGRESS'); +INSERT INTO room (total_round, current_round, time_limit, status, category) +VALUES (5, 2, 30000, 'PROGRESS', 'EXAMPLE'), + (5, 1, 30000, 'PROGRESS', 'EXAMPLE'), + (5, 1, 30000, 'PROGRESS', 'EXAMPLE'); INSERT INTO member (nickname, room_id, is_master) VALUES ('mohamedeu al katan', 1, true), From 25117e5b0d82d70395b5fdd41444cac4419b2008 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 1 Aug 2024 21:58:07 +0900 Subject: [PATCH 0441/1013] =?UTF-8?q?feat:=20=EB=B0=A9=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EB=B3=80=EA=B2=BD=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20#107?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../balance/room/RoomController.java | 10 +++ .../balance/room/dto/RoomInfoResponse.java | 3 +- .../balance/room/dto/RoomSettingRequest.java | 10 +++ .../balance/room/dto/RoomSettingResponse.java | 10 ++- .../ddangkong/domain/balance/room/Room.java | 15 ++++- .../service/balance/room/RoomService.java | 9 +++ .../balance/room/RoomControllerTest.java | 25 +++++++ .../domain/balance/room/RoomTest.java | 32 +++++++++ .../service/balance/room/RoomServiceTest.java | 66 +++++++++++++++++++ 9 files changed, 176 insertions(+), 4 deletions(-) create mode 100644 backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSettingRequest.java diff --git a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java index 8b24da75..fa2e3888 100644 --- a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java +++ b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java @@ -4,6 +4,7 @@ import ddangkong.controller.balance.room.dto.RoomInfoResponse; import ddangkong.controller.balance.room.dto.RoomJoinRequest; import ddangkong.controller.balance.room.dto.RoomJoinResponse; +import ddangkong.controller.balance.room.dto.RoomSettingRequest; import ddangkong.service.balance.room.RoomService; import jakarta.validation.Valid; import jakarta.validation.constraints.Positive; @@ -11,6 +12,7 @@ import org.springframework.http.HttpStatus; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -26,6 +28,7 @@ public class RoomController { private final RoomService roomService; + @ResponseStatus(HttpStatus.OK) @GetMapping("/balances/rooms/{roomId}") public RoomInfoResponse getBalanceGameRoomInfo(@Positive @PathVariable Long roomId) { return roomService.findRoomInfo(roomId); @@ -48,4 +51,11 @@ public RoomJoinResponse joinRoom(@PathVariable @Positive Long roomId, @Valid @Re public BalanceContentResponse moveToNextRound(@PathVariable @Positive Long roomId) { return roomService.moveToNextRound(roomId); } + + @ResponseStatus(HttpStatus.NO_CONTENT) + @PatchMapping("/balances/rooms/{roomId}") + public void updateRoomSetting(@PathVariable @Positive Long roomId, + @RequestBody RoomSettingRequest request) { + roomService.updateRoomSetting(roomId, request); + } } diff --git a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomInfoResponse.java b/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomInfoResponse.java index 2db0c7fa..a29e61cb 100644 --- a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomInfoResponse.java +++ b/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomInfoResponse.java @@ -14,7 +14,8 @@ public static RoomInfoResponse of(List members, Room room) { List membersResponse = members.stream() .map(MemberResponse::new) .toList(); - RoomSettingResponse roomSettingResponse = new RoomSettingResponse(room.getTotalRound(), room.getTimeLimit()); + RoomSettingResponse roomSettingResponse = new RoomSettingResponse(room.getTotalRound(), room.getTimeLimit(), + room.getCategory()); return new RoomInfoResponse(room.isGameProgress(), roomSettingResponse, membersResponse); } diff --git a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSettingRequest.java b/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSettingRequest.java new file mode 100644 index 00000000..9ab30d01 --- /dev/null +++ b/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSettingRequest.java @@ -0,0 +1,10 @@ +package ddangkong.controller.balance.room.dto; + +import ddangkong.domain.balance.content.Category; + +public record RoomSettingRequest( + int totalRound, + int timeLimit, + Category category +) { +} diff --git a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSettingResponse.java b/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSettingResponse.java index 035763ce..d8eed61a 100644 --- a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSettingResponse.java +++ b/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSettingResponse.java @@ -1,7 +1,15 @@ package ddangkong.controller.balance.room.dto; +import ddangkong.domain.balance.content.Category; +import ddangkong.domain.balance.room.Room; + public record RoomSettingResponse( int totalRound, - int timeLimit + int timeLimit, + Category category ) { + + public static RoomSettingResponse from(Room room) { + return new RoomSettingResponse(room.getTotalRound(), room.getTimeLimit(), room.getCategory()); + } } diff --git a/backend/src/main/java/ddangkong/domain/balance/room/Room.java b/backend/src/main/java/ddangkong/domain/balance/room/Room.java index a5b516b4..d85404b5 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/Room.java @@ -19,7 +19,10 @@ public class Room { private static final int DEFAULT_TOTAL_ROUND = 5; - private static final int DEFAULT_TIME_LIMIT_MSEC = 30_000; + private static final int MIN_TOTAL_ROUND = 3; + private static final int MAX_TOTAL_ROUND = 10; + private static final int MIN_TIME_LIMIT_MSEC = 10_000; + private static final int MAX_TIME_LIMIT_MSEC = 30_000; private static final int START_ROUND = 1; @Id @@ -44,7 +47,7 @@ public class Room { private Category category; public static Room createNewRoom() { - return new Room(DEFAULT_TOTAL_ROUND, START_ROUND, DEFAULT_TIME_LIMIT_MSEC, RoomStatus.READY, Category.EXAMPLE); + return new Room(DEFAULT_TOTAL_ROUND, START_ROUND, MAX_TIME_LIMIT_MSEC, RoomStatus.READY, Category.EXAMPLE); } public Room(int totalRound, int currentRound, int timeLimit, RoomStatus status, Category category) { @@ -64,10 +67,18 @@ public void moveToNextRound() { } public void updateTimeLimit(int timeLimit) { + if (timeLimit < MIN_TIME_LIMIT_MSEC || timeLimit > MAX_TIME_LIMIT_MSEC) { + throw new BadRequestException("시간 제한은 %dms 이상, %dms 이하만 가능합니다. requested timeLimit: %d" + .formatted(MIN_TIME_LIMIT_MSEC, MAX_TIME_LIMIT_MSEC, timeLimit)); + } this.timeLimit = timeLimit; } public void updateTotalRound(int totalRound) { + if (totalRound < MIN_TOTAL_ROUND || totalRound > MAX_TOTAL_ROUND) { + throw new BadRequestException("총 라운드는 %d 이상, %d 이하만 가능합니다. requested totalRound: %d" + .formatted(MIN_TOTAL_ROUND, MAX_TOTAL_ROUND, totalRound)); + } this.totalRound = totalRound; } diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index 58b4a970..986de61d 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -4,6 +4,7 @@ import ddangkong.controller.balance.member.dto.MemberResponse; import ddangkong.controller.balance.room.dto.RoomInfoResponse; import ddangkong.controller.balance.room.dto.RoomJoinResponse; +import ddangkong.controller.balance.room.dto.RoomSettingRequest; import ddangkong.domain.balance.option.BalanceOptionRepository; import ddangkong.domain.balance.option.BalanceOptions; import ddangkong.domain.balance.room.Room; @@ -70,4 +71,12 @@ private RoomContent findCurrentRoomContent(Room room) { return roomContentRepository.findByRoomAndRound(room, room.getCurrentRound()) .orElseThrow(() -> new BadRequestException("해당 방의 현재 진행중인 질문이 존재하지 않습니다.")); } + + @Transactional + public void updateRoomSetting(Long roomId, RoomSettingRequest request) { + Room room = roomRepository.getById(roomId); + + room.updateTimeLimit(request.timeLimit()); + room.updateTotalRound(request.totalRound()); + } } diff --git a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java index 3dd04d50..3e0f0150 100644 --- a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java @@ -8,6 +8,7 @@ import ddangkong.controller.balance.option.dto.BalanceOptionResponse; import ddangkong.controller.balance.room.dto.RoomInfoResponse; import ddangkong.controller.balance.room.dto.RoomJoinResponse; +import ddangkong.controller.balance.room.dto.RoomSettingRequest; import ddangkong.domain.balance.content.Category; import io.restassured.RestAssured; import io.restassured.http.ContentType; @@ -16,6 +17,7 @@ import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; class RoomControllerTest extends BaseControllerTest { @@ -151,4 +153,27 @@ class 다음_라운드_진행 { .statusCode(400); } } + + @Nested + class 방_설정_변경 { + + @Test + void 방_설정_정보를_변경한다() { + // given + int totalRound = 5; + int timeLimit = 10000; + Category category = Category.EXAMPLE; + + RoomSettingRequest request = new RoomSettingRequest(totalRound, timeLimit, category); + + // when & then + RestAssured.given().log().all() + .contentType(ContentType.JSON) + .pathParam("roomId", 1L) + .body(request) + .when().patch("/api/balances/rooms/{roomId}") + .then().log().all() + .statusCode(HttpStatus.NO_CONTENT.value()); + } + } } diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java index c5bf6d9e..4f8fe2e8 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java @@ -7,6 +7,8 @@ import ddangkong.exception.BadRequestException; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; class RoomTest { @@ -42,4 +44,34 @@ class 다음_라운드로_이동 { .hasMessage("마지막 라운드입니다."); } } + + @Nested + class 방_설정_변경 { + + @ParameterizedTest + @ValueSource(ints = {2, 11}) + void 라운드는_3이상_10이하_여야한다(int notValidTotalRound) { + // given + Room room = Room.createNewRoom(); + + // when & then + assertThatThrownBy(() -> room.updateTotalRound(notValidTotalRound)) + .isExactlyInstanceOf(BadRequestException.class) + .hasMessage("총 라운드는 %d 이상, %d 이하만 가능합니다. requested totalRound: %d" + .formatted(3, 10, notValidTotalRound)); + } + + @ParameterizedTest + @ValueSource(ints = {9000, 31000}) + void 시간_제한은_10000이상_30000이하_여야한다(int notValidTimeLimit) { + // given + Room room = Room.createNewRoom(); + + // when & then + assertThatThrownBy(() -> room.updateTimeLimit(notValidTimeLimit)) + .isExactlyInstanceOf(BadRequestException.class) + .hasMessage("시간 제한은 %dms 이상, %dms 이하만 가능합니다. requested timeLimit: %d" + .formatted(10000, 30000, notValidTimeLimit)); + } + } } diff --git a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java index 374e1852..f42a10d8 100644 --- a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java @@ -9,12 +9,16 @@ import ddangkong.controller.balance.option.dto.BalanceOptionResponse; import ddangkong.controller.balance.room.dto.RoomInfoResponse; import ddangkong.controller.balance.room.dto.RoomJoinResponse; +import ddangkong.controller.balance.room.dto.RoomSettingRequest; +import ddangkong.controller.balance.room.dto.RoomSettingResponse; import ddangkong.domain.balance.content.Category; import ddangkong.exception.BadRequestException; import ddangkong.service.BaseServiceTest; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.springframework.beans.factory.annotation.Autowired; class RoomServiceTest extends BaseServiceTest { @@ -128,4 +132,66 @@ class 다음_라운드로_이동 { .hasMessage("해당 방의 현재 진행중인 질문이 존재하지 않습니다."); } } + + @Nested + class 방_설정_변경 { + + @Test + void 방_설정_정보를_변경한다() { + // given + Long roomId = 2L; + int totalRound = 5; + int timeLimit = 10000; + Category category = Category.EXAMPLE; + + RoomSettingRequest request = new RoomSettingRequest(totalRound, timeLimit, category); + + // when + roomService.updateRoomSetting(roomId, request); + + // then + RoomInfoResponse roomInfo = roomService.findRoomInfo(roomId); + RoomSettingResponse roomSetting = roomInfo.roomSetting(); + + assertAll( + () -> assertThat(roomSetting.totalRound()).isEqualTo(totalRound), + () -> assertThat(roomSetting.timeLimit()).isEqualTo(timeLimit), + () -> assertThat(roomSetting.category()).isEqualTo(category) + ); + } + + @ParameterizedTest + @ValueSource(ints = {2, 11}) + void 라운드는_3이상_10이하_여야한다(int notValidTotalRound) { + // given + Long roomId = 2L; + int timeLimit = 10000; + Category category = Category.EXAMPLE; + + RoomSettingRequest request = new RoomSettingRequest(notValidTotalRound, timeLimit, category); + + // when & then + assertThatThrownBy(() -> roomService.updateRoomSetting(roomId, request)) + .isExactlyInstanceOf(BadRequestException.class) + .hasMessage("총 라운드는 %d 이상, %d 이하만 가능합니다. requested totalRound: %d" + .formatted(3, 10, notValidTotalRound)); + } + + @ParameterizedTest + @ValueSource(ints = {9000, 31000}) + void 시간_제한은_10000이상_30000이하_여야한다(int notValidTimeLimit) { + // given + Long roomId = 2L; + int totalRound = 5; + Category category = Category.EXAMPLE; + + RoomSettingRequest request = new RoomSettingRequest(totalRound, notValidTimeLimit, category); + + // when & then + assertThatThrownBy(() -> roomService.updateRoomSetting(roomId, request)) + .isExactlyInstanceOf(BadRequestException.class) + .hasMessage("시간 제한은 %dms 이상, %dms 이하만 가능합니다. requested timeLimit: %d" + .formatted(10000, 30000, notValidTimeLimit)); + } + } } From 6e5d336e855e8f0d33747e7c2619933dca0bf70d Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 1 Aug 2024 22:04:25 +0900 Subject: [PATCH 0442/1013] =?UTF-8?q?docs:=20RestDocs=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=9E=91=EC=84=B1=20=EB=B0=8F=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=88=98=EC=A0=95=20#107?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/docs/asciidoc/room.adoc | 20 ++++++++++ .../balance/room/RoomDocumentationTest.java | 37 ++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/backend/src/docs/asciidoc/room.adoc b/backend/src/docs/asciidoc/room.adoc index 92361ad5..bb889e1f 100644 --- a/backend/src/docs/asciidoc/room.adoc +++ b/backend/src/docs/asciidoc/room.adoc @@ -85,3 +85,23 @@ include::{snippets}/room/next/http-response.adoc[] response fields include::{snippets}/room/next/response-fields.adoc[] + +=== 방 설정 변경 + +==== curl + +include::{snippets}/room/setting/curl-request.adoc[] + +==== request + +include::{snippets}/room/setting/http-request.adoc[] + +include::{snippets}/room/setting/path-parameters.adoc[] + +==== response + +include::{snippets}/room/setting/http-response.adoc[] + +response fields + +include::{snippets}/room/setting/response-fields.adoc[] diff --git a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java index 012f3e2d..5680266a 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java @@ -6,6 +6,7 @@ import static org.mockito.Mockito.when; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; import static org.springframework.restdocs.payload.JsonFieldType.BOOLEAN; import static org.springframework.restdocs.payload.JsonFieldType.NUMBER; @@ -24,6 +25,7 @@ import ddangkong.controller.balance.room.dto.RoomInfoResponse; import ddangkong.controller.balance.room.dto.RoomJoinRequest; import ddangkong.controller.balance.room.dto.RoomJoinResponse; +import ddangkong.controller.balance.room.dto.RoomSettingRequest; import ddangkong.controller.balance.room.dto.RoomSettingResponse; import ddangkong.documentation.BaseDocumentationTest; import ddangkong.domain.balance.content.Category; @@ -124,9 +126,10 @@ class 방_정보_조회 { //given int totalRound = 5; int timeLimit = 30000; + Category category = Category.EXAMPLE; RoomInfoResponse response = new RoomInfoResponse( false, - new RoomSettingResponse(totalRound, timeLimit), + new RoomSettingResponse(totalRound, timeLimit, category), List.of( new MemberResponse(1L, "땅콩", true), new MemberResponse(2L, "타콩", false) @@ -147,6 +150,7 @@ class 방_정보_조회 { fieldWithPath("roomSetting").type(JsonFieldType.OBJECT).description("현재 방 설정 값"), fieldWithPath("roomSetting.totalRound").type(NUMBER).description("전체 라운드"), fieldWithPath("roomSetting.timeLimit").type(NUMBER).description("라운드 당 시간제한(ms)"), + fieldWithPath("roomSetting.category").type(STRING).description("컨텐츠 카테고리"), fieldWithPath("members").type(JsonFieldType.ARRAY).description("방에 참여중 인원 목록"), fieldWithPath("members[].memberId").type(NUMBER).description("멤버 ID"), fieldWithPath("members[].nickname").type(STRING).description("멤버 닉네임"), @@ -200,4 +204,35 @@ class 다음_라운드로_이동 { )); } } + + @Nested + class 방_설정_변경 { + + private static final String ENDPOINT = "/api/balances/rooms/{roomId}"; + + @Test + void 방의_설정_정보를_변경한다() throws Exception { + // given + int totalRound = 5; + int timeLimit = 30_000; + Category category = Category.EXAMPLE; + RoomSettingRequest content = new RoomSettingRequest(totalRound, timeLimit, category); + + // then + mockMvc.perform(patch(ENDPOINT, 1L) + .content(objectMapper.writeValueAsString(content)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isNoContent()) + .andDo(document("room/setting", + pathParameters( + parameterWithName("roomId").description("방 ID") + ), + requestFields( + fieldWithPath("totalRound").type(NUMBER).description("변경할 총 라운드"), + fieldWithPath("timeLimit").type(NUMBER).description("변경할 제한 시간"), + fieldWithPath("category").type(STRING).description("변경할 카테고리") + ) + )); + } + } } From 7e104d13eac0f92237c5f3102df5ca1e470ddd83 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 1 Aug 2024 22:04:53 +0900 Subject: [PATCH 0443/1013] =?UTF-8?q?refactor:=20restDocs=20default=20host?= =?UTF-8?q?=EB=AA=85=20=ED=99=95=EC=A0=95=EB=90=9C=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EC=A3=BC=EC=86=8C=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?#107?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ddangkong/documentation/BaseDocumentationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/test/java/ddangkong/documentation/BaseDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/BaseDocumentationTest.java index 76b2fcfc..095a50b4 100644 --- a/backend/src/test/java/ddangkong/documentation/BaseDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/BaseDocumentationTest.java @@ -34,7 +34,7 @@ void setUp(WebApplicationContext context, RestDocumentationContextProvider restD .withRequestDefaults( modifyUris() .scheme("https") - .host("ddangkong.io") + .host("ddangkong.kr") .removePort(), prettyPrint(), modifyHeaders().remove(HttpHeaders.CONTENT_LENGTH) From 1e1cd5d91414283068a202bfa6de97f6122dbacb Mon Sep 17 00:00:00 2001 From: novice0840 Date: Fri, 2 Aug 2024 14:18:37 +0900 Subject: [PATCH 0444/1013] =?UTF-8?q?feat:=20ReadyMembersContainer=20?= =?UTF-8?q?=EC=8A=A4=ED=86=A0=EB=A6=AC=20=EB=B6=81=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?#92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/assets/images/crownIcon.png | Bin 0 -> 420 bytes .../ReadyMembersContainer.stories.ts | 18 ++++++++++++++++++ .../ReadyMembersContainer.styled.ts | 7 +++++++ .../ReadyMembersContainer.tsx | 14 ++++++++------ .../data/{roomMembers.json => roomInfo.json} | 0 5 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 frontend/src/assets/images/crownIcon.png create mode 100644 frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.stories.ts rename frontend/src/mocks/data/{roomMembers.json => roomInfo.json} (100%) diff --git a/frontend/src/assets/images/crownIcon.png b/frontend/src/assets/images/crownIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..3c3ccb45da4a81fdf885631fa39627ce17b25cd7 GIT binary patch literal 420 zcmV;V0bBlwP)&9D*aj21V*7y#glyZjc>P5vp^8?n`VYPFp)_(nb#I zml97r<2N&!$UqO7?{rc8a zOfQ1X0y2K@gi5%|I;ym1nPHpZ%sH>4Ht43h!~yrK^k5?x$^{J6#roZ#2kzaZ7Rztpz{XI?ys-OX8M_#<_V*!bd7d<`03)FqS}vw{b!!5 z19ZS&&w__i6F)FiS{DxJ1`{rxum>cCp=!2Ve+-iTRSp=(3Ijz~kFG*GpRVkrgK7WJ z;mJf>!(Ier5`>7fqRWSQWk$Qr2)F$EOb{Y1KlwecOtITE<_)3phVlmq<9kmq=G*81 O0000#WEC literal 0 HcmV?d00001 diff --git a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.stories.ts b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.stories.ts new file mode 100644 index 00000000..33488fe4 --- /dev/null +++ b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.stories.ts @@ -0,0 +1,18 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import ReadyMembersContainer from './ReadyMembersContainer'; + +import roomInfo from '@/mocks/data/roomInfo.json'; + +const meta: Meta = { + component: ReadyMembersContainer, +}; + +export const 기본값: Story = { + args: { + members: roomInfo.members, + }, +}; + +export default meta; +type Story = StoryObj; diff --git a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.styled.ts b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.styled.ts index 4d950f8c..42f5d207 100644 --- a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.styled.ts +++ b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.styled.ts @@ -3,6 +3,12 @@ import { css } from '@emotion/react'; import { Theme } from '@/styles/Theme'; export const readyMembersContainerLayout = css` + display: flex; + flex-direction: column; + gap: 2rem; +`; + +export const membersContainer = css` position: relative; height: 25rem; padding: 2rem 3rem 0; @@ -57,4 +63,5 @@ export const memberStatus = css` display: flex; flex: 1; justify-content: space-between; + align-items: center; `; diff --git a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx index f1bc7911..74fb057a 100644 --- a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx +++ b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx @@ -5,17 +5,19 @@ import { memberList, profileBox, memberStatus, + membersContainer, } from './ReadyMembersContainer.styled'; +import crownIcon from '@/assets/images/crownIcon.png'; import { RoomMembers } from '@/types/room'; interface ReadyMembersContainerProps extends RoomMembers {} const ReadyMembersContainer = ({ members }: ReadyMembersContainerProps) => { return ( - <> -
    총 인원 5명
    -
    +
    +
    총 인원 {members.length}명
    +
    • +
      @@ -23,16 +25,16 @@ const ReadyMembersContainer = ({ members }: ReadyMembersContainerProps) => {
    • {members.map((member) => (
    • -
      +
      +
      {member.nickname} - {member.isMaster && 왕관} + {member.isMaster && 왕관 아이콘}
    • ))}
    - +
    ); }; diff --git a/frontend/src/mocks/data/roomMembers.json b/frontend/src/mocks/data/roomInfo.json similarity index 100% rename from frontend/src/mocks/data/roomMembers.json rename to frontend/src/mocks/data/roomInfo.json From 89ce3d35d1aae8881b6ce5b7ed9742bb24987567 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Fri, 2 Aug 2024 14:20:56 +0900 Subject: [PATCH 0445/1013] =?UTF-8?q?refactor:=20ResponseStatus=20?= =?UTF-8?q?=EA=B8=B0=EB=B3=B8=20=EC=84=A4=EC=A0=95=EA=B0=92=EC=9D=80=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=EC=97=90=EC=84=9C=20=EC=A0=9C=EA=B1=B0=20#10?= =?UTF-8?q?7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ddangkong/controller/balance/room/RoomController.java | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java index fa2e3888..b6c9f220 100644 --- a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java +++ b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java @@ -28,7 +28,6 @@ public class RoomController { private final RoomService roomService; - @ResponseStatus(HttpStatus.OK) @GetMapping("/balances/rooms/{roomId}") public RoomInfoResponse getBalanceGameRoomInfo(@Positive @PathVariable Long roomId) { return roomService.findRoomInfo(roomId); From acc969ce54f26f53d76c034a242b908a337afad5 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Fri, 2 Aug 2024 14:22:22 +0900 Subject: [PATCH 0446/1013] =?UTF-8?q?feat:=20=EC=B9=B4=ED=85=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B5=AC=ED=98=84=20#107?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/main/java/ddangkong/domain/balance/room/Room.java | 4 ++++ .../main/java/ddangkong/service/balance/room/RoomService.java | 1 + 2 files changed, 5 insertions(+) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/Room.java b/backend/src/main/java/ddangkong/domain/balance/room/Room.java index d85404b5..e3b31f8e 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/Room.java @@ -82,6 +82,10 @@ public void updateTotalRound(int totalRound) { this.totalRound = totalRound; } + public void updateCategory(Category category) { + this.category = category; + } + private boolean canMoveToNextRound() { return currentRound < totalRound; } diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index 986de61d..376be952 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -78,5 +78,6 @@ public void updateRoomSetting(Long roomId, RoomSettingRequest request) { room.updateTimeLimit(request.timeLimit()); room.updateTotalRound(request.totalRound()); + room.updateCategory(request.category()); } } From c107e6eaffce9f98bd813acb712c7e0c1350d173 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Fri, 2 Aug 2024 14:36:55 +0900 Subject: [PATCH 0447/1013] =?UTF-8?q?fix:=20router=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20#92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/assets/images/plusIcon.png | Bin 0 -> 319 bytes .../ReadyMembersContainer.tsx | 5 ++++- frontend/src/pages/NicknamePage/NicknamePage.tsx | 11 +++++------ frontend/src/pages/ReadyPage/ReadyPage.tsx | 7 +++---- frontend/src/router/index.tsx | 4 ++-- 5 files changed, 14 insertions(+), 13 deletions(-) create mode 100644 frontend/src/assets/images/plusIcon.png diff --git a/frontend/src/assets/images/plusIcon.png b/frontend/src/assets/images/plusIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..b85d165edec9e5fbc120f27bbc77085d52927501 GIT binary patch literal 319 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRt!3HF+tk*dLq&N#aB8wRqxP?KOkzv*x37{Zj zage(c!@6@aFM%AEbVpxD28NCO+978G??@l_%dB{P)wcKn{FyBWpjuuVD zX$kDN8p9TaEt1V(pO)|@fs>_(M{&7BSbB52=^MRHamDvW^$*UsOR~*qwde~z|M{F( zdF*!mE+yliV%r#`_5~g6-xnM?t7gtkN8fg{$=V4b|M_3^OSlUD+P6QkFLttu<*VA; z+oo^QVO2=dSX#5;{o-E7E2Vpbw3pcPXd7@eg|Mz*7tFC*lsSv%mqydI8@xR2j`f#H zj#}>LWSYThb<6wxXB+dX^ba2E8oVwi6*0tC@-p~Ol6<-L?02>mYfKCz*X`d3^dEz# LtDnm{r-UW|E_rgh literal 0 HcmV?d00001 diff --git a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx index 74fb057a..20d327e4 100644 --- a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx +++ b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx @@ -9,6 +9,7 @@ import { } from './ReadyMembersContainer.styled'; import crownIcon from '@/assets/images/crownIcon.png'; +import plusIcon from '@/assets/images/plusIcon.png'; import { RoomMembers } from '@/types/room'; interface ReadyMembersContainerProps extends RoomMembers {} @@ -20,7 +21,9 @@ const ReadyMembersContainer = ({ members }: ReadyMembersContainerProps) => {
    • -
      +
      +
      + 추가 아이콘 +
      초대하기
    • {members.map((member) => ( diff --git a/frontend/src/pages/NicknamePage/NicknamePage.tsx b/frontend/src/pages/NicknamePage/NicknamePage.tsx index ed56bbf4..17190d77 100644 --- a/frontend/src/pages/NicknamePage/NicknamePage.tsx +++ b/frontend/src/pages/NicknamePage/NicknamePage.tsx @@ -1,6 +1,6 @@ import { useMutation } from '@tanstack/react-query'; import { useRef } from 'react'; -import { useLocation, useNavigate } from 'react-router-dom'; +import { useLocation, useNavigate, useParams } from 'react-router-dom'; import { useRecoilState } from 'recoil'; import { profile, nicknameBox, nicknameInputWrapper, nicknameInput } from './NicknamePage.styled'; @@ -17,14 +17,13 @@ const NicknamePage = () => { const nicknameInputRef = useRef(null); const navigate = useNavigate(); const [{ isMaster }, setMemberInfo] = useRecoilState(memberInfoState); - const { search } = useLocation(); - const roomId = Number(new URLSearchParams(search).get('roomId')); + const { roomId } = useParams(); const nickname = nicknameInputRef.current?.value || randomNickname; const makeRoomMutation = useMutation({ mutationFn: makeRoom, onSuccess: (data) => { - navigate(`/ready?roomId=${data.roomId}`); + navigate(`/ready/${data.roomId}`); }, onError: (error: Error) => {}, }); @@ -32,7 +31,7 @@ const NicknamePage = () => { const enterRoomMutation = useMutation({ mutationFn: ({ nickname, roomId }) => enterRoom(roomId, nickname), onSuccess: () => { - navigate(`/ready?roomId=${roomId}`); + navigate(`/ready/${roomId}`); }, onError: (error: Error) => {}, }); @@ -41,7 +40,7 @@ const NicknamePage = () => { if (isMaster) { makeRoomMutation.mutate(nickname); } else { - enterRoomMutation.mutate({ nickname, roomId }); + enterRoomMutation.mutate({ nickname, roomId: Number(roomId) }); } }; diff --git a/frontend/src/pages/ReadyPage/ReadyPage.tsx b/frontend/src/pages/ReadyPage/ReadyPage.tsx index 2d4fab52..b4ee380b 100644 --- a/frontend/src/pages/ReadyPage/ReadyPage.tsx +++ b/frontend/src/pages/ReadyPage/ReadyPage.tsx @@ -1,5 +1,5 @@ import { useQuery } from '@tanstack/react-query'; -import { useLocation } from 'react-router-dom'; +import { useLocation, useParams } from 'react-router-dom'; import { useRecoilValue } from 'recoil'; import { readyPageLayout } from './ReadyPage.styled'; @@ -13,11 +13,10 @@ import { memberInfoState } from '@/recoil/atom'; const ReadyPage = () => { const memberInfo = useRecoilValue(memberInfoState); - const { search } = useLocation(); - const roomId = Number(new URLSearchParams(search).get('roomId')); + const { roomId } = useParams(); const { data, isLoading, isError } = useQuery({ - queryKey: [QUERY_KEYS.roomMembers, roomId], + queryKey: [QUERY_KEYS.roomMembers, Number(roomId)], queryFn: ({ queryKey: [_, roomId] }) => getRoomMembers(roomId as number), refetchInterval: 1000, }); diff --git a/frontend/src/router/index.tsx b/frontend/src/router/index.tsx index 537a8707..fb44a415 100644 --- a/frontend/src/router/index.tsx +++ b/frontend/src/router/index.tsx @@ -24,11 +24,11 @@ export const router = createBrowserRouter([ element: , children: [ { - path: 'nickname', + path: 'nickname/:roomId?', element: , }, { - path: 'ready', + path: 'ready/:roomId', element: , }, { From a71609c327b85cf638c9804bc33554ccfd0a723d Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Fri, 2 Aug 2024 14:39:37 +0900 Subject: [PATCH 0448/1013] =?UTF-8?q?feat:=20RoomContent=EC=97=90=EC=84=9C?= =?UTF-8?q?=20=ED=95=B4=EB=8B=B9=20=EB=9D=BC=EC=9A=B4=EB=93=9C=EB=A5=BC=20?= =?UTF-8?q?=EC=8B=9C=EC=9E=91=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 라운드 마감 시간 설정 --- .../domain/balance/room/RoomContent.java | 34 ++++++++++ .../domain/balance/room/RoomContentTest.java | 67 +++++++++++++++++++ backend/src/test/resources/init-test.sql | 10 +-- 3 files changed, 106 insertions(+), 5 deletions(-) create mode 100644 backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java index 22ab7f88..cc08891b 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java @@ -3,6 +3,7 @@ import ddangkong.domain.BaseEntity; import ddangkong.domain.balance.content.BalanceContent; import ddangkong.domain.balance.content.Category; +import ddangkong.exception.BadRequestException; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; @@ -11,6 +12,7 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; +import java.time.LocalDateTime; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -20,6 +22,8 @@ @Getter public class RoomContent extends BaseEntity { + private static final int DELAY_MSEC = 2_000; // TODO SEC로 변경 + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @@ -35,6 +39,36 @@ public class RoomContent extends BaseEntity { @Column(nullable = false) private int round; + private LocalDateTime roundEndedAt; + + @Column(nullable = false) + private boolean isUsed; + + public RoomContent(Room room, BalanceContent balanceContent, int round) { + this.room = room; + this.balanceContent = balanceContent; + this.round = round; + this.roundEndedAt = null; + this.isUsed = false; + } + + public void startRound(LocalDateTime currentTime) { + if (roundEndedAt != null) { + throw new BadRequestException("해당 라운드는 이미 시작했습니다."); + } + if (room.isGameProgress() && isDifferentToRoomRound()) { + throw new BadRequestException("방이 해당 라운드가 아닙니다 roomRound : %d, contentRound : %d" + .formatted(room.getCurrentRound(), round)); + } + + int afterSec = (room.getTimeLimit() + DELAY_MSEC) / 1_000; + roundEndedAt = currentTime.plusSeconds(afterSec); + } + + private boolean isDifferentToRoomRound() { + return round != room.getCurrentRound(); + } + public Long getContentId() { return balanceContent.getId(); } diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java new file mode 100644 index 00000000..dd5a3f76 --- /dev/null +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java @@ -0,0 +1,67 @@ +package ddangkong.domain.balance.room; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import ddangkong.domain.balance.content.BalanceContent; +import ddangkong.domain.balance.content.Category; +import ddangkong.exception.BadRequestException; +import java.time.LocalDateTime; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +class RoomContentTest { + + @Nested + class 라운드_시작 { + + private static final BalanceContent BALANCE_CONTENT = new BalanceContent(Category.EXAMPLE, "다음 중 가고 싶은 곳은?"); + private static final LocalDateTime CURRENT_TIME = LocalDateTime.of(2024, 8, 2, 14, 14, 10); + + @Test + void 라운드를_시작할_때_종료_시각을_기록한다() { + // given + int currentRound = 1; + int timeLimit = 10_000; + LocalDateTime currentTime = LocalDateTime.of(2024, 8, 2, 14, 14, 10); + Room room = new Room(5, currentRound, timeLimit, RoomStatus.PROGRESS); + RoomContent roomContent = new RoomContent(room, BALANCE_CONTENT, currentRound); + int expectedAfterSec = (timeLimit + 2_000) / 1_000; + LocalDateTime expectedRoundEnded = currentTime.plusSeconds(expectedAfterSec); + + // when + roomContent.startRound(currentTime); + + // then + assertThat(roomContent.getRoundEndedAt()).isEqualTo(expectedRoundEnded); + } + + @Test + void 이미_라운드가_시작되었다면_예외를_던진다() { + // given + int currentRound = 1; + Room room = new Room(5, currentRound, 10_000, RoomStatus.PROGRESS); + RoomContent roomContent = new RoomContent(room, BALANCE_CONTENT, currentRound); + roomContent.startRound(CURRENT_TIME); + + // when & then + assertThatThrownBy(() -> roomContent.startRound(CURRENT_TIME)) + .isInstanceOf(BadRequestException.class) + .hasMessage("해당 라운드는 이미 시작했습니다."); + } + + @Test + void 방의_진행_라운드와_일치하지_않으면_예외를_던진다() { + // given + int roomRound = 1; + int roomContentRound = 2; + Room room = new Room(5, roomRound, 10_000, RoomStatus.PROGRESS); + RoomContent roomContent = new RoomContent(room, BALANCE_CONTENT, roomContentRound); + + // when & then + assertThatThrownBy(() -> roomContent.startRound(CURRENT_TIME)) + .isInstanceOf(BadRequestException.class) + .hasMessage("방이 해당 라운드가 아닙니다 roomRound : 1, contentRound : 2"); + } + } +} diff --git a/backend/src/test/resources/init-test.sql b/backend/src/test/resources/init-test.sql index f874c45a..9c77edd1 100644 --- a/backend/src/test/resources/init-test.sql +++ b/backend/src/test/resources/init-test.sql @@ -16,11 +16,11 @@ VALUES ('EXAMPLE', '민초 vs 반민초'), ('EXAMPLE', '월 200 백수 vs 월 500 직장인'), ('EXAMPLE', '다음 중 여행가고 싶은 곳은?'); -INSERT INTO room_content (room_id, balance_content_id, round, created_at) -VALUES (1, 2, 1, '2024-07-18 19:50:00.000'), - (1, 1, 2, '2024-07-18 20:00:00.000'), - (1, 3, 3, '2024-07-18 20:00:00.000'), - (3, 1, 1, '2024-07-18 19:51:00.000'); +INSERT INTO room_content (room_id, balance_content_id, round, created_at, round_ended_at, is_used) +VALUES (1, 2, 1, '2024-07-18 19:50:00.000', '2024-07-18 19:50:32.000', false), + (1, 1, 2, '2024-07-18 19:50:00.000', '2024-07-18 20:00:32.000', false), + (1, 3, 3, '2024-07-18 19:50:00.000', null, false), + (3, 1, 1, '2024-07-18 20:00:00.000', '2024-07-18 20:00:32.000', false); INSERT INTO balance_option (name, balance_content_id) VALUES ('민초', 1), From 6f8c9e9940ac967e8139349aa07c0276965913c4 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Fri, 2 Aug 2024 14:40:58 +0900 Subject: [PATCH 0449/1013] =?UTF-8?q?feat:=20=EB=8B=A4=EC=9D=8C=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B4=EB=93=9C=EB=A1=9C=20=EB=84=98=EC=96=B4?= =?UTF-8?q?=EA=B0=80=EB=8A=94=20=EA=B8=B0=EB=8A=A5=EC=97=90=20RoomContent?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=9D=BC=EC=9A=B4=EB=93=9C=20=EC=8B=9C?= =?UTF-8?q?=EC=9E=91=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/balance/room/RoomService.java | 16 ++++++++++++++++ .../service/balance/room/RoomServiceTest.java | 10 +++++++++- backend/src/test/resources/init-test.sql | 12 ++++++++++-- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index fbb6d9a5..1c790b28 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -4,9 +4,13 @@ import ddangkong.controller.balance.room.dto.RoomInfoResponse; import ddangkong.controller.balance.room.dto.RoomJoinResponse; import ddangkong.domain.balance.room.Room; +import ddangkong.domain.balance.room.RoomContent; +import ddangkong.domain.balance.room.RoomContentRepository; import ddangkong.domain.balance.room.RoomRepository; import ddangkong.domain.member.Member; import ddangkong.domain.member.MemberRepository; +import ddangkong.exception.InternalServerException; +import java.time.LocalDateTime; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -20,6 +24,8 @@ public class RoomService { private final MemberRepository memberRepository; + private final RoomContentRepository roomContentRepository; + @Transactional(readOnly = true) public RoomInfoResponse findRoomInfo(Long roomId) { Room room = roomRepository.getById(roomId); @@ -46,5 +52,15 @@ public RoomJoinResponse joinRoom(String nickname, Long roomId) { public void moveToNextRound(Long roomId) { Room room = roomRepository.getById(roomId); room.moveToNextRound(); + + if (room.isGameProgress()) { + RoomContent roomContent = getCurrentRoomContent(room); + roomContent.startRound(LocalDateTime.now()); // TODO #105와 merge될 때 수정 예정 + } + } + + private RoomContent getCurrentRoomContent(Room room) { + return roomContentRepository.findByRoomAndRound(room, room.getCurrentRound()) + .orElseThrow(() -> new InternalServerException("해당 룸에서 진행 중인 라운드 컨텐츠가 존재하지 않습니다.")); } } diff --git a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java index 7edc877e..095753c8 100644 --- a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java @@ -11,6 +11,8 @@ import ddangkong.controller.balance.room.dto.RoomJoinResponse; import ddangkong.domain.balance.content.Category; import ddangkong.domain.balance.room.Room; +import ddangkong.domain.balance.room.RoomContent; +import ddangkong.domain.balance.room.RoomContentRepository; import ddangkong.domain.balance.room.RoomRepository; import ddangkong.domain.balance.room.RoomStatus; import ddangkong.exception.BadRequestException; @@ -28,6 +30,9 @@ class RoomServiceTest extends BaseServiceTest { @Autowired private RoomRepository roomRepository; + @Autowired + private RoomContentRepository roomContentRepository; + @Nested class 게임_방_정보_조회 { @@ -120,9 +125,12 @@ class 다음_라운드로_이동 { // then Room room = roomRepository.getById(PROGRESS_ROOM_ID); + RoomContent roomContent = roomContentRepository.findByRoomAndRound(room, room.getCurrentRound()) + .orElseThrow(); assertAll( () -> assertThat(room.getCurrentRound()).isEqualTo(nextRound), - () -> assertThat(room.isGameProgress()).isTrue() + () -> assertThat(room.isGameProgress()).isTrue(), + () -> assertThat(roomContent.getRoundEndedAt()).isNotNull() ); } diff --git a/backend/src/test/resources/init-test.sql b/backend/src/test/resources/init-test.sql index 9c77edd1..94d4a8ce 100644 --- a/backend/src/test/resources/init-test.sql +++ b/backend/src/test/resources/init-test.sql @@ -14,12 +14,16 @@ VALUES ('mohamedeu al katan', 1, true), INSERT INTO balance_content (category, name) VALUES ('EXAMPLE', '민초 vs 반민초'), ('EXAMPLE', '월 200 백수 vs 월 500 직장인'), - ('EXAMPLE', '다음 중 여행가고 싶은 곳은?'); + ('EXAMPLE', '다음 중 여행가고 싶은 곳은?'), + ('EXAMPLE', '팔만대장경 다 읽기 vs 대장내시경 팔만번 하기'), + ('EXAMPLE', '개구리 맛 초콜릿 vs 초콜릿 맛 개구리'); INSERT INTO room_content (room_id, balance_content_id, round, created_at, round_ended_at, is_used) VALUES (1, 2, 1, '2024-07-18 19:50:00.000', '2024-07-18 19:50:32.000', false), (1, 1, 2, '2024-07-18 19:50:00.000', '2024-07-18 20:00:32.000', false), (1, 3, 3, '2024-07-18 19:50:00.000', null, false), + (1, 4, 4, '2024-07-18 19:50:00.000', null, false), + (1, 5, 5, '2024-07-18 19:50:00.000', null, false), (3, 1, 1, '2024-07-18 20:00:00.000', '2024-07-18 20:00:32.000', false); INSERT INTO balance_option (name, balance_content_id) @@ -28,7 +32,11 @@ VALUES ('민초', 1), ('월 200 백수', 2), ('월 200 직장인', 2), ('산', 3), - ('바다', 3); + ('바다', 3), + ('팔만대장경 다 읽기', 4), + ('대장내시경 팔만번 하기', 4), + ('개구리 맛 초콜릿', 5), + ('초콜릿 맛 개구리', 5); INSERT INTO balance_vote (balance_option_id, member_id) VALUES (4, 1), From a7874eea5f809d9f2781b70889a39745a9601740 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Fri, 2 Aug 2024 14:41:14 +0900 Subject: [PATCH 0450/1013] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20adoc=20=EC=8A=A4=EB=8B=88=ED=8E=AB=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0=20#93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/docs/asciidoc/room.adoc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/backend/src/docs/asciidoc/room.adoc b/backend/src/docs/asciidoc/room.adoc index 2fb56ec5..035d4e2d 100644 --- a/backend/src/docs/asciidoc/room.adoc +++ b/backend/src/docs/asciidoc/room.adoc @@ -62,10 +62,6 @@ include::{snippets}/room/setting/path-parameters.adoc[] include::{snippets}/room/setting/http-response.adoc[] -response fields - -include::{snippets}/room/setting/response-fields.adoc[] - === 방 정보 조회 ==== curl From 7833e3722e3659208a2b68d140a4b5a728d59bf7 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Fri, 2 Aug 2024 14:41:55 +0900 Subject: [PATCH 0451/1013] =?UTF-8?q?design:=20=EB=95=85=EC=BD=A9=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=B6=94=EA=B0=80=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/assets/images/ddangkong.png | Bin 0 -> 93123 bytes frontend/src/components/Timer/Timer.tsx | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 frontend/src/assets/images/ddangkong.png diff --git a/frontend/src/assets/images/ddangkong.png b/frontend/src/assets/images/ddangkong.png new file mode 100644 index 0000000000000000000000000000000000000000..67c3eb221c6365caabba8568b0f32a19c24e5680 GIT binary patch literal 93123 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 z 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 { const { barWidth, timerCount, isAlmostFinished } = useRoundTimer(); @@ -20,7 +20,7 @@ const Timer = () => {
      타이머 Date: Fri, 2 Aug 2024 14:58:07 +0900 Subject: [PATCH 0452/1013] =?UTF-8?q?refactor:=20'my'=20prefix=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20#93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/docs/asciidoc/room.adoc | 2 +- .../balance/room/RoomController.java | 6 ++-- .../ddangkong/domain/balance/room/Room.java | 6 ++-- .../service/balance/room/RoomService.java | 4 +-- .../balance/room/RoomControllerTest.java | 6 ++-- .../balance/room/RoomDocumentationTest.java | 12 ++++---- .../domain/balance/room/RoomTest.java | 30 +++++++++---------- .../service/balance/room/RoomServiceTest.java | 26 ++++++++-------- 8 files changed, 46 insertions(+), 46 deletions(-) diff --git a/backend/src/docs/asciidoc/room.adoc b/backend/src/docs/asciidoc/room.adoc index 035d4e2d..52f8da60 100644 --- a/backend/src/docs/asciidoc/room.adoc +++ b/backend/src/docs/asciidoc/room.adoc @@ -102,7 +102,7 @@ response fields include::{snippets}/room/next/response-fields.adoc[] -=== 나의 라운드 종료 여부 + === 라운드 종료 여부 ==== curl diff --git a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java index 0d29aba3..f598f618 100644 --- a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java +++ b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java @@ -61,8 +61,8 @@ public BalanceContentResponse moveToNextRound(@PathVariable @Positive Long roomI } @GetMapping("/balances/rooms/{roomId}/round-finished") - public RoundFinishedResponse getMyRoundFinished(@Positive @PathVariable Long roomId, - @Positive @RequestParam int myRound) { - return roomService.getMyRoundFinished(roomId, myRound); + public RoundFinishedResponse getRoundFinished(@Positive @PathVariable Long roomId, + @Positive @RequestParam int round) { + return roomService.getRoundFinished(roomId, round); } } diff --git a/backend/src/main/java/ddangkong/domain/balance/room/Room.java b/backend/src/main/java/ddangkong/domain/balance/room/Room.java index d3b71d40..99e663dc 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/Room.java @@ -95,9 +95,9 @@ public boolean isGameProgress() { return status.isGameProgress(); } - public boolean isMyRoundFinished(int myRound) { - validateRound(myRound); - return currentRound != myRound; + public boolean isRoundFinished(int round) { + validateRound(round); + return currentRound != round; } private void validateRound(int round) { diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index 16f9b803..1dd15dd6 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -83,8 +83,8 @@ public void updateRoomSetting(Long roomId, RoomSettingRequest request) { } @Transactional(readOnly = true) - public RoundFinishedResponse getMyRoundFinished(Long roomId, int myRound) { + public RoundFinishedResponse getRoundFinished(Long roomId, int round) { Room room = roomRepository.getById(roomId); - return new RoundFinishedResponse(room.isMyRoundFinished(myRound), room.isAllRoundFinished()); + return new RoundFinishedResponse(room.isRoundFinished(round), room.isAllRoundFinished()); } } diff --git a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java index 0c762c3c..82e46410 100644 --- a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java @@ -179,14 +179,14 @@ class 방_설정_변경 { } @Nested - class 나의_라운드_종료_여부 { + class 라운드_종료_여부 { @Test - void 나의_라운드가_종료되었는지_조회한다() { + void 라운드가_종료되었는지_조회한다() { // when RoundFinishedResponse actual = RestAssured.given().log().all() .pathParam("roomId", 1L) - .queryParam("myRound", 1) + .queryParam("round", 1) .when().get("/api/balances/rooms/{roomId}/round-finished") .then().log().all() .statusCode(200) diff --git a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java index 8aaa37ba..e96155a6 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java @@ -238,19 +238,19 @@ class 방_설정_변경 { } @Nested - class 나의_라운드_종료_여부 { + class 라운드_종료_여부 { private static final String ENDPOINT = "/api/balances/rooms/{roomId}/round-finished"; @Test - void 나의_라운드가_종료되었는지_조회한다() throws Exception { + void 라운드가_종료되었는지_조회한다() throws Exception { // given RoundFinishedResponse response = new RoundFinishedResponse(true, false); - when(roomService.getMyRoundFinished(anyLong(), anyInt())).thenReturn(response); + when(roomService.getRoundFinished(anyLong(), anyInt())).thenReturn(response); // when & then mockMvc.perform(get(ENDPOINT, 1) - .param("myRound", "1") + .param("round", "1") ) .andExpect(status().isOk()) .andDo(document("room/roundFinished", @@ -258,10 +258,10 @@ class 나의_라운드_종료_여부 { parameterWithName("roomId").description("방 ID") ), queryParameters( - parameterWithName("myRound").description("나의 라운드") + parameterWithName("round").description("라운드") ), responseFields( - fieldWithPath("isRoundFinished").description("나의 라운드 종료 여부"), + fieldWithPath("isRoundFinished").description("라운드 종료 여부"), fieldWithPath("isGameFinished").description("게임 종료 여부") ) )); diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java index 3174ba43..803ea61c 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java @@ -85,61 +85,61 @@ class 라운드_종료 { private static final Category CATEGORY = Category.EXAMPLE; @Test - void 나의_라운드가_방의_현재_라운드보다_작으면_나의_라운드는_종료된_것이다() { + void 라운드가_방의_현재_라운드보다_작으면_라운드는_종료된_것이다() { // given int currentRound = 2; Room room = new Room(TOTAL_ROUND, currentRound, TIME_LIMIT, STATUS, CATEGORY); - int myRound = 1; + int round = 1; // when & then - assertThat(room.isMyRoundFinished(myRound)).isTrue(); + assertThat(room.isRoundFinished(round)).isTrue(); } @Test - void 나의_라운드와_방의_현재_라운드와_같으면_나의_라운드는_종료되지_않은_것이다() { + void 라운드가_방의_현재_라운드와_같으면_라운드는_종료되지_않은_것이다() { // given int currentRound = 2; Room room = new Room(TOTAL_ROUND, currentRound, TIME_LIMIT, STATUS, CATEGORY); - int myRound = 2; + int round = 2; // when & then - assertThat(room.isMyRoundFinished(myRound)).isFalse(); + assertThat(room.isRoundFinished(round)).isFalse(); } @Test - void 나의_라운드가_방의_시작_라운드보다_작으면_예외가_발생한다() { + void 라운드가_방의_시작_라운드보다_작으면_예외가_발생한다() { // given Room room = new Room(TOTAL_ROUND, 1, TIME_LIMIT, STATUS, CATEGORY); - int invalidMyRound = 0; + int invalidRound = 0; // when & then - assertThatThrownBy(() -> room.isMyRoundFinished(invalidMyRound)) + assertThatThrownBy(() -> room.isRoundFinished(invalidRound)) .isExactlyInstanceOf(BadRequestException.class) .hasMessageContaining("startRound보다 크거나 같아야 합니다. startRound : 1, round : 0"); } @Test - void 나의_라운드가_방의_현재_라운드보다_크면_예외가_발생한다() { + void 라운드가_방의_현재_라운드보다_크면_예외가_발생한다() { // given int currentRound = 1; Room room = new Room(TOTAL_ROUND, currentRound, TIME_LIMIT, STATUS, CATEGORY); - int invalidMyRound = 2; + int invalidRound = 2; // when & then - assertThatThrownBy(() -> room.isMyRoundFinished(invalidMyRound)) + assertThatThrownBy(() -> room.isRoundFinished(invalidRound)) .isExactlyInstanceOf(BadRequestException.class) .hasMessageContaining("currentRound보다 작거나 같아야 합니다. currentRound : 1, round : 2"); } @Test - void 나의_라운드가_방의_현재_라운드보다_2이상_작으면_예외가_발생한다() { + void 라운드가_방의_현재_라운드보다_2이상_작으면_예외가_발생한다() { // given int currentRound = 4; Room room = new Room(TOTAL_ROUND, currentRound, TIME_LIMIT, STATUS, CATEGORY); - int invalidMyRound = 2; + int invalidRound = 2; // when & then - assertThatThrownBy(() -> room.isMyRoundFinished(invalidMyRound)) + assertThatThrownBy(() -> room.isRoundFinished(invalidRound)) .isExactlyInstanceOf(BadRequestException.class) .hasMessageContaining("currentRound과 round의 차이는 1이하여야 합니다. currentRound : 4, round : 2"); } diff --git a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java index d4995bfd..3dde6489 100644 --- a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java @@ -203,7 +203,7 @@ class 방_설정_변경 { } @Nested - class 나의_라운드_종료_여부 { + class 라운드_종료_여부 { private static final int TOTAL_ROUND = 5; private static final int TIME_LIMIT = 30_000; @@ -211,15 +211,15 @@ class 나의_라운드_종료_여부 { private static final Category CATEGORY = Category.EXAMPLE; @Test - void 나의_라운드가_종료되지_않았으면_게임도_종료되지_않은_상태여야_한다() { + void 라운드가_종료되지_않았으면_게임도_종료되지_않은_상태여야_한다() { // given int currentRound = 2; Room room = roomRepository.save( new Room(TOTAL_ROUND, currentRound, TIME_LIMIT, STATUS, CATEGORY)); - int myRound = 2; + int round = 2; // when - RoundFinishedResponse roundFinishedResponse = roomService.getMyRoundFinished(room.getId(), myRound); + RoundFinishedResponse roundFinishedResponse = roomService.getRoundFinished(room.getId(), round); // then assertAll( @@ -229,14 +229,14 @@ class 나의_라운드_종료_여부 { } @Test - void 나의_라운드가_종료되면_게임은_종료되지_않은_상태여야_한다() { + void 라운드가_종료되면_게임은_종료되지_않은_상태여야_한다() { // given int currentRound = 2; Room room = roomRepository.save(new Room(TOTAL_ROUND, currentRound, TIME_LIMIT, STATUS, CATEGORY)); - int myRound = 1; + int round = 1; // when - RoundFinishedResponse roundFinishedResponse = roomService.getMyRoundFinished(room.getId(), myRound); + RoundFinishedResponse roundFinishedResponse = roomService.getRoundFinished(room.getId(), round); // then assertAll( @@ -246,15 +246,15 @@ class 나의_라운드_종료_여부 { } @Test - void 게임이_종료되면_나의_라운드는_종료되지_않은_상태여야_한다() { + void 게임이_종료되면_라운드는_종료되지_않은_상태여야_한다() { // given int currentRound = 5; RoomStatus status = RoomStatus.FINISH; Room room = roomRepository.save(new Room(TOTAL_ROUND, currentRound, TIME_LIMIT, status, CATEGORY)); - int myRound = 5; + int round = 5; // when - RoundFinishedResponse roundFinishedResponse = roomService.getMyRoundFinished(room.getId(), myRound); + RoundFinishedResponse roundFinishedResponse = roomService.getRoundFinished(room.getId(), round); // then assertAll( @@ -264,14 +264,14 @@ class 나의_라운드_종료_여부 { } @Test - void 현재_마지막_라운드여도_게임이_종료되지_않은_상태이면_나의_라운드도_종료되지_않은_상태여야_한다() { + void 현재_마지막_라운드여도_게임이_종료되지_않은_상태이면_라운드도_종료되지_않은_상태여야_한다() { // given int currentRound = 5; Room room = roomRepository.save(new Room(TOTAL_ROUND, currentRound, TIME_LIMIT, STATUS, CATEGORY)); - int myRound = 5; + int round = 5; // when - RoundFinishedResponse roundFinishedResponse = roomService.getMyRoundFinished(room.getId(), myRound); + RoundFinishedResponse roundFinishedResponse = roomService.getRoundFinished(room.getId(), round); // then assertAll( From 78e2bc917bd2a47bac95aa3901cc90df2cfdf431 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Fri, 2 Aug 2024 15:11:34 +0900 Subject: [PATCH 0453/1013] =?UTF-8?q?refactor:=20=EC=A1=B0=EA=B1=B4?= =?UTF-8?q?=EB=AC=B8=20=ED=86=B5=ED=95=A9=20#93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/main/java/ddangkong/domain/balance/room/Room.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/Room.java b/backend/src/main/java/ddangkong/domain/balance/room/Room.java index 99e663dc..63a07237 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/Room.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/Room.java @@ -111,7 +111,7 @@ private void validateRound(int round) { .formatted(currentRound, round) ); } - if (round < currentRound && currentRound - round != ALLOWED_ROUND_GAP) { + if (currentRound - round > ALLOWED_ROUND_GAP) { throw new BadRequestException("currentRound과 round의 차이는 %d이하여야 합니다. currentRound : %d, round : %d" .formatted(ALLOWED_ROUND_GAP, currentRound, round) ); From 42b53c77f4ec87c69296fc17d0f4cd10b2cf2984 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Fri, 2 Aug 2024 15:11:46 +0900 Subject: [PATCH 0454/1013] =?UTF-8?q?refactor:=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=EB=AA=85=20=EB=B3=80=EA=B2=BD=20#93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/test/java/ddangkong/domain/balance/room/RoomTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java index 803ea61c..9c9d3980 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java @@ -167,7 +167,7 @@ class 라운드_종료 { @ParameterizedTest @EnumSource(mode = Mode.EXCLUDE, names = {"FINISH"}) - void 방_상태가_FINISH가_아니면_방의_전체_라운드가_종료되지_않은_것이다(RoomStatus status) { + void 방_상태가_FINISH가_아니면_현재_라운드가_전체_라운드와_같아도_전체_라운드는_종료되지_않은_것이다(RoomStatus status) { // given Room room = new Room(TOTAL_ROUND, 5, TIME_LIMIT, status, CATEGORY); From 1c7d51f62f0166ecbc55f9d8e95c7665e3f06187 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Fri, 2 Aug 2024 15:15:32 +0900 Subject: [PATCH 0455/1013] =?UTF-8?q?refactor:=20hook=20=EB=B6=84=EB=A6=AC?= =?UTF-8?q?=20#92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/room.ts | 10 ++-- frontend/src/constants/url.ts | 2 +- .../src/pages/NicknamePage/NicknamePage.tsx | 43 ++--------------- .../pages/NicknamePage/useMakeOrEnterRoom.ts | 46 +++++++++++++++++++ frontend/src/pages/ReadyPage/ReadyPage.tsx | 28 ++--------- frontend/src/pages/ReadyPage/useGameStart.ts | 16 +++++++ .../src/pages/ReadyPage/useGetRoomInfo.ts | 17 +++++++ frontend/src/types/room.ts | 2 +- 8 files changed, 94 insertions(+), 70 deletions(-) create mode 100644 frontend/src/pages/NicknamePage/useMakeOrEnterRoom.ts create mode 100644 frontend/src/pages/ReadyPage/useGameStart.ts create mode 100644 frontend/src/pages/ReadyPage/useGetRoomInfo.ts diff --git a/frontend/src/apis/room.ts b/frontend/src/apis/room.ts index f270a317..f14eff73 100644 --- a/frontend/src/apis/room.ts +++ b/frontend/src/apis/room.ts @@ -25,7 +25,7 @@ export const makeRoom = async (nickname: string): Promise => { }; // 방 참여하기 -export const enterRoom = async (roomId: number, nickname: string): Promise => { +export const enterRoom = async (roomId: number, nickname: string): Promise => { const res = await fetcher.post({ url: API_URL.enterRoom(roomId), headers: { @@ -45,14 +45,14 @@ export const enterRoom = async (roomId: number, nickname: string): Promise => { +// 방 정보 조회 +export const getRoomInfo = async (roomId: number): Promise => { const res = await fetcher.get({ - url: API_URL.roomMembers(roomId), + url: API_URL.getRoomInfo(roomId), }); if (!res.ok) { - throw new Error('방 멤버 가져오기에 실패하였습니다'); + throw new Error('방 정보 가져오기에 실패하였습니다'); } const data = await res.json(); diff --git a/frontend/src/constants/url.ts b/frontend/src/constants/url.ts index 9d1cfa17..31703053 100644 --- a/frontend/src/constants/url.ts +++ b/frontend/src/constants/url.ts @@ -10,7 +10,7 @@ export const API_URL = { finalResult: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/final`, room: `${BASE_URL}/api/balances/rooms`, enterRoom: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/members`, - roomMembers: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}`, + getRoomInfo: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}`, }; export const MOCK_API_URL = { diff --git a/frontend/src/pages/NicknamePage/NicknamePage.tsx b/frontend/src/pages/NicknamePage/NicknamePage.tsx index 17190d77..21694044 100644 --- a/frontend/src/pages/NicknamePage/NicknamePage.tsx +++ b/frontend/src/pages/NicknamePage/NicknamePage.tsx @@ -1,48 +1,11 @@ -import { useMutation } from '@tanstack/react-query'; -import { useRef } from 'react'; -import { useLocation, useNavigate, useParams } from 'react-router-dom'; -import { useRecoilState } from 'recoil'; - import { profile, nicknameBox, nicknameInputWrapper, nicknameInput } from './NicknamePage.styled'; +import { useMakeOrEnterRoom } from './useMakeOrEnterRoom'; -import { enterRoom, makeRoom } from '@/apis/room'; import Button from '@/components/common/Button/Button'; import Content from '@/components/layout/Content/Content'; -import { memberInfoState } from '@/recoil/atom'; -import { RoomAndMember, RoomInfo } from '@/types/room'; -import { createRandomNickname } from '@/utils/nickname'; const NicknamePage = () => { - const randomNickname = createRandomNickname(); - const nicknameInputRef = useRef(null); - const navigate = useNavigate(); - const [{ isMaster }, setMemberInfo] = useRecoilState(memberInfoState); - const { roomId } = useParams(); - const nickname = nicknameInputRef.current?.value || randomNickname; - - const makeRoomMutation = useMutation({ - mutationFn: makeRoom, - onSuccess: (data) => { - navigate(`/ready/${data.roomId}`); - }, - onError: (error: Error) => {}, - }); - - const enterRoomMutation = useMutation({ - mutationFn: ({ nickname, roomId }) => enterRoom(roomId, nickname), - onSuccess: () => { - navigate(`/ready/${roomId}`); - }, - onError: (error: Error) => {}, - }); - - const handleClick = () => { - if (isMaster) { - makeRoomMutation.mutate(nickname); - } else { - enterRoomMutation.mutate({ nickname, roomId: Number(roomId) }); - } - }; + const { randomNickname, nicknameInputRef, handleMakeOrEnterRoom } = useMakeOrEnterRoom(); return ( @@ -56,7 +19,7 @@ const NicknamePage = () => { ref={nicknameInputRef} />
      - + ); }; diff --git a/frontend/src/pages/NicknamePage/useMakeOrEnterRoom.ts b/frontend/src/pages/NicknamePage/useMakeOrEnterRoom.ts new file mode 100644 index 00000000..f518750a --- /dev/null +++ b/frontend/src/pages/NicknamePage/useMakeOrEnterRoom.ts @@ -0,0 +1,46 @@ +import { useMutation } from '@tanstack/react-query'; +import { useRef } from 'react'; +import { useNavigate, useParams } from 'react-router-dom'; +import { useRecoilValue } from 'recoil'; + +import { enterRoom, makeRoom } from '@/apis/room'; +import { memberInfoState } from '@/recoil/atom'; +import { RoomAndMember } from '@/types/room'; +import { createRandomNickname } from '@/utils/nickname'; + +export const useMakeOrEnterRoom = () => { + const randomNickname = createRandomNickname(); + const nicknameInputRef = useRef(null); + const navigate = useNavigate(); + const { isMaster } = useRecoilValue(memberInfoState); + const { roomId } = useParams(); + const nickname = nicknameInputRef.current?.value || randomNickname; + + const makeRoomMutation = useMutation({ + mutationFn: makeRoom, + onSuccess: (data) => { + navigate(`/ready/${data.roomId}`); + }, + onError: (error: Error) => {}, + }); + + const enterRoomMutation = useMutation( + { + mutationFn: ({ nickname, roomId }) => enterRoom(roomId, nickname), + onSuccess: () => { + navigate(`/ready/${roomId}`); + }, + onError: (error: Error) => {}, + }, + ); + + const handleMakeOrEnterRoom = () => { + if (isMaster) { + makeRoomMutation.mutate(nickname); + } else { + enterRoomMutation.mutate({ nickname, roomId: Number(roomId) }); + } + }; + + return { randomNickname, nicknameInputRef, handleMakeOrEnterRoom }; +}; diff --git a/frontend/src/pages/ReadyPage/ReadyPage.tsx b/frontend/src/pages/ReadyPage/ReadyPage.tsx index b4ee380b..a08cb95f 100644 --- a/frontend/src/pages/ReadyPage/ReadyPage.tsx +++ b/frontend/src/pages/ReadyPage/ReadyPage.tsx @@ -1,32 +1,14 @@ -import { useQuery } from '@tanstack/react-query'; -import { useLocation, useParams } from 'react-router-dom'; -import { useRecoilValue } from 'recoil'; - import { readyPageLayout } from './ReadyPage.styled'; +import { useGameStart } from './useGameStart'; +import { useGetRoomInfo } from './useGetRoomInfo'; -import { getRoomMembers } from '@/apis/room'; import CategoryContainer from '@/components/CategoryContainer/CategoryContainer'; import Button from '@/components/common/Button/Button'; import ReadyMembersContainer from '@/components/ReadyMembersContainer/ReadyMembersContainer'; -import { QUERY_KEYS } from '@/constants/queryKeys'; -import { memberInfoState } from '@/recoil/atom'; const ReadyPage = () => { - const memberInfo = useRecoilValue(memberInfoState); - const { roomId } = useParams(); - - const { data, isLoading, isError } = useQuery({ - queryKey: [QUERY_KEYS.roomMembers, Number(roomId)], - queryFn: ({ queryKey: [_, roomId] }) => getRoomMembers(roomId as number), - refetchInterval: 1000, - }); - - const handleGameStart = () => { - if (memberInfo.isMaster) { - // TODO: 게임 시작 API 연결 예정 - alert('Game Start'); - } - }; + const { data, isLoading, isError } = useGetRoomInfo(); + const { isMaster, handleGameStart } = useGameStart(); return (
      @@ -34,7 +16,7 @@ const ReadyPage = () => { {isError &&
      에러 발생
      } {isLoading &&
      로딩중.......
      } {data && } -
      ); }; diff --git a/frontend/src/pages/ReadyPage/useGameStart.ts b/frontend/src/pages/ReadyPage/useGameStart.ts new file mode 100644 index 00000000..cbf6852f --- /dev/null +++ b/frontend/src/pages/ReadyPage/useGameStart.ts @@ -0,0 +1,16 @@ +import { useRecoilValue } from 'recoil'; + +import { memberInfoState } from '@/recoil/atom'; + +export const useGameStart = () => { + const memberInfo = useRecoilValue(memberInfoState); + + const handleGameStart = () => { + if (memberInfo.isMaster) { + // TODO: 게임 시작 API 연결 예정 + alert('Game Start'); + } + }; + + return { isMaster: memberInfo.isMaster, handleGameStart }; +}; diff --git a/frontend/src/pages/ReadyPage/useGetRoomInfo.ts b/frontend/src/pages/ReadyPage/useGetRoomInfo.ts new file mode 100644 index 00000000..4f04bcc7 --- /dev/null +++ b/frontend/src/pages/ReadyPage/useGetRoomInfo.ts @@ -0,0 +1,17 @@ +import { useQuery } from '@tanstack/react-query'; +import { useParams } from 'react-router-dom'; + +import { getRoomInfo } from '@/apis/room'; +import { QUERY_KEYS } from '@/constants/queryKeys'; + +export const useGetRoomInfo = () => { + const { roomId } = useParams(); + + const { data, isLoading, isError } = useQuery({ + queryKey: [QUERY_KEYS.roomMembers, Number(roomId)], + queryFn: ({ queryKey: [_, roomId] }) => getRoomInfo(roomId as number), + refetchInterval: 1000, + }); + + return { data, isLoading, isError }; +}; diff --git a/frontend/src/types/room.ts b/frontend/src/types/room.ts index fc2ca827..0ff066b4 100644 --- a/frontend/src/types/room.ts +++ b/frontend/src/types/room.ts @@ -12,7 +12,7 @@ interface RoomSetting { export interface RoomInfo { isGameStart: boolean; roomSetting: RoomSetting; - member: Member; + members: Member[]; } export interface RoomMembers { From 8416d4f667a389f7eb02cbcd0169fc6668ccfdee Mon Sep 17 00:00:00 2001 From: novice0840 Date: Fri, 2 Aug 2024 15:30:09 +0900 Subject: [PATCH 0456/1013] =?UTF-8?q?feat:=20=EB=A9=94=EC=9D=B8=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20hook=20=EB=B6=84=EB=A6=AC=20#92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/assets/images/logoIcon.png | Bin 0 -> 27841 bytes frontend/src/pages/MainPage/MainPage.tsx | 24 ++++++------------- frontend/src/pages/MainPage/useCreateRoom.ts | 20 ++++++++++++++++ 3 files changed, 27 insertions(+), 17 deletions(-) create mode 100644 frontend/src/assets/images/logoIcon.png create mode 100644 frontend/src/pages/MainPage/useCreateRoom.ts diff --git a/frontend/src/assets/images/logoIcon.png b/frontend/src/assets/images/logoIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..b5c81df667bc5b6665cb7f3d118fb91bd3d5fc42 GIT binary patch literal 27841 zcmXtf2{e@d_y0392HDHLCE2rvtXZOBvR1aNgTmNl-)BCFio~ewG?~awF=U-mwAdQE zv5Zn08B`3JnE&JZKfliDQ0KYNbKm!U?|r}Sy|4FOds_=`4lxb@0JssB=dS<&6#Nwm zu(N_cw&KS3z#lA;W(Ws%@J|x^^*i9dkAz!Ziv*vaI{XVUQ!I`H|5G&Tf=krZFu$l+ z@0&M(*w|P#RA^A7uXp$jwXmE1#p`Fq0N@0GIDgI|u4HXKe(t;PU*@l=#JZU_6=`X2 z6;!kGjSp(qu%-4&0+%n}!(JaDotiQ8y8T}0)X`%fg=S)JEZz@USTq?PF!aE8eCWwmG`?+o5@nUFNLjDwZ9&%@d4W3&}(o1IU=1Voe4#1%HD?x`F#o7vVv*} zTC27U)Dp`r-w|&Uq|{36*rmBH2>|<+MdB{pF0FfCU%dUBBvRB1QGhZ18MoiO0>2`= z9R)doiXgEiFJ>J0+|c6iSazhiQv@hC$-bN`{ATQ5sfExdf!IIi`kBP?+JGxK=d&Co ztR+5-VbX^*K4??~D6WGPTv!K&m)ZM%pQ4f|mkAq6C06XXj3@{2%|b{I z65GMv+hWG3Q9rboExRe%hI-wMeZFxU6pu&SWo^_^s98jhF~*9q$XQ|P6(6JR;ZsV7iC$VKB!V0N$v zc3)O{iJ8{_UK>@0jEu?-v8%9j`5!asPKe)fM~>(TfxGTR2ftW?58D^_;~phgL` z%5m>6ymSTM!L?C`d0A(`NuE2?HFy1|V!X^|JX!bgp*1~UaiTfzgdJS{trC{{erNw5 zTRWMqEXV&74tnpoQ|x>9{*$BrJ9i}vGLTos-Q!?T2*%oVWk8n3Em3&m*YF>)aNe-g z_6Llnw*BiL-oAM&J7lqH`bxSooE4O#5hnr3;?8F$f^)0%P9`D;^F};~)pg=96sH{b~NrpO1 zeE#$Z_i#0y)lB`+SoRm^;Y0!v)v7w3C5~PMQWcV?2kuifg0bHfBzf0(2A%avm0s~q z8>q3Tj}`}lE*Hj(9WA_-?5Pm)hne_ad1r91r)KkLp{xyOFl^1dbEB_|C+P$I?lb-) z(%QAdP-G(Ip{r2P16@S^zPt+8dW%uzbswCTLo(|m8y)VXUNXG=Ph|H}V^kKG^tc<~ z&a2|}$%m#Z)Lwp<^Om8Hrdxpk;!_?6#s<-sJNx|NJmkCqAl;lI)!3?3i23}`i>@J8e@pX84z=^rU1sS`lTBDC|Z@=yhF}bQ;Yj52u zvuRHG`Yf`LSW9dmq?$VIA-?T z8GLvHbN?qof$NPM5yoXNF`d$d^u)1F{CVAt4ufe4*j9~95HEgSHAq|6dn$f&S5SCt(ygB=*acXLX@c1_t1j&4^nur*du)rKAWdxH!O7G#>p^lJ2h%)o zI?6D-nC5RKFC=eA5+XhbuyB5zh-nR3^a2<7=KcK^pk2b{WlxkD7ZvLMUENN#}X4trbtU_3a0AIXiJfHBL%nkkPGjQ>+UFB*Ky%9R>#u!xsOPA>uQ2eY#=_Oi(EP9-XVfSWFzX~Kh-cqdy zotp8C$7fm=9d#*d`xrXRCZxo7V2pfJ zAjxNz$Xx}r^ShiiS5uztG4AW&&(#)eQvCmz<5-J7)UDt}2Kp-Is_&TnaPw0@P3(Z3-}|ph$TE^Hv9@q+!~5UUCmRp+6OO0t{kyNNy&^#l zdt_T_BWuGg!Ip$G-PH;XyLuv&-J2ub6-YX!r*3|{m(U%O9vviug2=0JU4%tG98|Vm zPN9fU@a@VP#t1g(q7vU8nb7NeD5eRDNnBh#=h;RJE-&+*Uy~i`dwbz^0J01l4=;nI zuu6yzr7y@+KM_A`lU+U${eziaw@#b0U)30gQp89XIy#1Y8F#sU3dx{&Sk<_0ZrQQt z(OIj{4d)WVluE6|EoU)X*s2dJFB+k>i$SN143rf zi)u2-3`=zt`F~2k9(NXd0BegsC4bi3{ci=Lbw-5lMGPc(g&v9l=1M>hcN{4q*8r(I5y#x_kFw|CKEFw&c$#eyJ?H4r)i*Z0)Q|e z?)QG_7J*slJ>Q^!GN5#WX=!vh>__QZG(~~96S5NbWj4X_Xt@5+I?GxpBaQXzZ9aL8 z=g=n!QcQtullVl@f-?&tQ+6an(bP6%_3FyJ+@HW^VKARo1oyfa6jmbkL{JJ(s&n5o zLX<6jNtx;2QUxBf9F$5Qcm?PGu%CQcgSuyxJ1f1jAA$NZ<5RAHX@n{4xE6aOe&(&S zSdZDi@5JzK`@9x36XzlT(}KJ4>ANOP-Kpu(eSD4{#~H#b$*Bvq7Dt>RUQMMHn<1(Q zx12H?o#-}M19-aqdn6}14*Y-pDQZcUSvEU34GjR!FZa zsHo-a-EmM+|LV@^;nUvQX&R!Srt9(^I<@4v?u1`8d5*DWLSJa5|J|^ZDOhyYY|L7R z^;~CQNq4m`kjn5g95!)+E(>%T_d8B$jXNNcjb1G4MSV2+2HV4yRErB|$_qjowFT7E%5)2$$g7lCQJ?bA#7?fC>5rfHtEroxVm0Qd zGhbO$ii1p#&>vVSVBK2B{(#;M?bT#gG9JrPHVsE`(23Af_`MK)0q|w@fnV;x( z!C~;OJO_4(i)GGoHU)6KbEFFs>n>9@p67z?Ru`tyO6BV3?d$jw7LYMux^)`lGZX{1 z^$?se@f>RQh_WCA`k@xCzSc5uxXIs z9A9&_`J42cWKj7}@>pd+d=ZprO+9}zw?%W)zetIcP3Vq=MVS3ST|ET|$5mRuU~quEMT|E$aw|KgCxX97`X~dkV1Ee_Osp zHiZ0vCg%8C)ToU?1^{71O=9Rpw>1kfiHGDD#3`{m{AMFXS0GIemF<^-H0kF37qqX4 zp>$(zcQ3tXAFk!Mh&M%1&#(F=sx(QW{LDhxEM2=WdeU3?D~3SZ4OiW$SF5O{8GHf~zNmoO~r1+h%f-9)Ar2+u5> z={E+lDE0XC7opo8e?Uqhbzt`JZ8y3=VUiu!L#t=GSMpG z=HEpYbF`m1eV0!A5by$sI}!)(oOD(JZ6!EWY`XBD+jQQa%M>4kme8R0`QTponpwhj z-Y16T&?7VUzVYjj@M4AS?;2^3o05-ho}*O$hpK~?EPfb(OkC~e*UXqv|Fb6@)q0l$ zK>Pvp{R$T!c@Oag`ZLt7@Mg&<>7v59Nhfe9j(3fHJLnay2Ie`$&+G0cX$?A~Jf;mG z#@DJBH=_mjh9*iOJt%k0P<6Z|Gu65aAtu}sSbgg?XqtvK7!Mkvj)qITS3@g_e#8%w zNlP@B-#tw(9#`fit;~NMf$dkmaHw361&!;+LE3#Q>9 z;__iTk#??WpQ8yZTtCinPCJr5!@o=}MNzy&rxxu=nxa#@IAv}JV7b8g;3-W(t4`d^ zw}$7xMY)hq`EjRqAK8{j+IJuPb?xW-*pFPmpb4hGjX4$d*Cj|+k2Kq zPkL~;H!rnE@A~z(R>{r6GBjlQg@8Z)_x=|O6U~!FL_zM1vg5nm_*h+u*z>`Q?Cy_G zzf}{R;=%p2b^%m!lx#r0X z@0k?tY3QzFA1+_+499B0aR`CQ@=wP1j)zu*q?t1+kd4w~{WE=(V*)5CMbK^)x17Ti z$ZYpz1%*kY2w6WfM$Z%}0t@(mb=!O|YRitSn=gC{h5fyUAJLVFlpU5^4992;*Rt2Y)vz~p7qU~6@8jsCNN8Oi?0l+M3^ns2e@``c2;tTh=^(%dd{*!oG)I3S; zEBMIm2)OC?kas`VX)w(c+`(Uvtv^XM!d9x5+NlwC*iz<@?}ub*lgO^zUBT*GUOaAy zBDup?-##z|ez9m=m!tY(vvZ=@s8jD2(G1LKY}vyt3xu0hQBQDXE4j4g+x)|d8mD*l zPOUT}^|9YtQ1Xq#1!{x}q48i1p!qf~bwcONmLft6qL7#VgR4K1c#Vi4MD~b=W#OyQ zi_l_if#0^2K7tjOs+cw+D7Vp&5<>93gk;YHEkN8aoaB}?1uKYNtzF(!^bA@Zn6m0{ zBza;N3gup>J0wGmVeSj|@8!^6#qOOs=A5&!bLW{{eG!VrXW+?%o*3XnI|ug`fM*$` zMwB)MtFUMqBoQwYE3m`4EuN|$1nr}_<^(YO#>b zMXsRq;RrpAAe$f?SQ1COC23Kv{@Pf_{Thxh_tBO8lLzNXiQt#rd!Y*-Tj<}h-v?V_ z*dQp?;JV?zf^k^nGCne=Le)lOYKwqTz=Y}%aN!n+qBfjMU&PVPxXRW=&Zyg%;%N=`p|y9{O;6S?z6;gH)0mHq5{?wHPtmg3;@XzS-YuqJ-)>42Ot4 z4z$DylP?xXaBT3hGe0f1+lk+=l|Ng5gP~7)Mm)`(W_XUY23kUs%w)ZJCZ$MhTK~}b z@Y4`>eQOT`%tvjouh4tRwIxb3&zIpu8om(v2Wp|i=ihES+)iJa_2fz)#m^Z6mw~NH z`QerfA3=&2*40R1f&Spblz4A%scikcX~~ivf1K*rEGP7*Kj@p;d5LT%vVnxLN2cV2 z(Giw^?j*Qsm~xlaW;iUuHb>hA7Lopz{*w3?48$8mzEjC?(`>ERDn8|}(4HyN=Npzq^%y<#Xr;d?OcD56@uACtU0P{QvNN!Fs&wG`Aosru zq>g9&g=x1iy?)uJ6*h+kPp8)6iO_o1IzGgq)TnFf|5rD*|Rt1h1BE(aocjJ-D?cgN}UqBm6QkD)DfUOixPQ(KmjOmg_X zoiRv{CPsrf%AJ&Oc(_blboABq|JW4c8we+OXwZZo28HGM{<~7ZT0gIo<1_oUO))G2#D;q&=w!t;_c4N zZ~9S^Mf>I;DvtB>0k>=7dh@&Z6HcG0$s_v7!M^c_ACh4ln7Zm+n?KFu<1`qZF?0Q$e7Fe$$PC;CNGk0S(=jU z2&)AFlHzZ7AT6sNDHn3FNYZ%x_3;YCE$>;4dNpez{VO3>A-dY|XxvMr!5D0%t=jhq zO&R0m$Mfg@;7{HG_4f>k-}A)vLmNK2DFiewyEu^2@fhhoqbaW}2bRHWUQRe$g4By{ zU;FZ(z zi@b@uZs1zi1=Cafx+mRosR7LPbmkh~-zR#u;`_FlA0Z5^-Pp#~NKWd++jhjh~2FB@i6n``Ka$=m)z+U*nW~Pp9EU zVb?ls>3?`AZ&xo|5?{0G@yCwk7-$oQa+eqX{=IB9Ae&)dYiKT#GHgZv2|8m!YP z61$3<8R=#XJV^~Wm%JMcAxc-4bWG^wW*C~b^4_E?z>hLsz|YrlO<^7qC-Qz`fEj?O z(5jadLo#k4`L87Yke850WvBbte87oLc?#?vTIZ(-{4u@XTsq5X=%2FRN;;2g)|O?~o0nal+D~r1ApGv; zI&=*iLG!N7Hc6QHJEu%lK`3jB=#H-#66?XJ@gxmsHkb%hK}W8;GRClepIYdarNG>RX^E;_ z$QZbU7vdMnFsEL*L72zlbRx43Dp?6E2Wr$nL@}XW|5AZAxiOF9RY^tK&R{$J$;@$B z$z#-CQOnrtt^@R9?VSxu9D-9vKshb=rXbMh=Mq`6`Z#vo7Mb_r)TSXx64Nd)E*;F| z+zka!p&V@w&|SW~%?g^*$96gqnCG>Gq5d%2yXp|!*tb(aQJht($mRy?7weB~=ufg9 z$N1rf{WxNB;bd9v_{nxXavNmohHFX-{(+xsCr@H7^BWs}{Z4%Wm*|`DZym6l{bKvp z`cBTjtT?Vo1EM2VNV&wK;J?7)-KH#Qo%ii@`~8z&XG0d?amRO)%$Il`wS<~Cn?3hv zkVIc3nAM6eC}>&%Y5U$l^oGfQ86h2o9=<^ zI#+%ZmYz>VsgiryhJzL7zTodZJ#8Tyl@+Q71&DO1fPwlsMZlnML$jXo`SCpb!(Ww# z)_e$K1{U`e=TeK6XCvIuInSOqaRv^?h7@EV|IYjf7AvGwVqO3xw_#V--?x|+tGzEh z*TZTle#!O3*lg?bbh8k_Z9RvVqN;aT6#qe)n7-v1AmAF)$ zw^??Rhdvo!_{2f1fqiMzN}pE!I@{X3uZSwReAV#Q7-R(@HgDg>mo7UciSFM6tnbo3 zVQ!!!#W><^%p=TQo;K~{Gast0#Jm$!XK0^5@Zw5s4R z);0F79DVoUyOB6Q5V^0{1nFPN!%a3Pb8e1Uf65$=J2qWKWdIwjYFKSIusdDwv`i7$ zn>L2KJWgus9cfGUt!yr}*kDonAmS5=PzHM`888gkX^2dqv|)`G!{_+=kAkzupfin$jkKM~F2Aoe zw80x_IrIfYe)@s=-ehX>c8@_+bznb(L<}IcwB=(g5cx)igdce=I-3Jo(hV*9%~?OE z8j8N`2qWJ?mwNpfWcZi#;|dfv;!dFFjvQHQs>_cZCyx!46V!bbjAT4Ld_3V@xDj>6 zbIg{d$G+R19e1?CQh0h*=jx}6Pt*DOW39h$^U_+H+X+mIz##XhMq6t528@=#9m#}o z#oyhx@86A+ZkcNQKo(9FC8=a*UpZqv`_QkPjXuNIZbmAB`(zv!fSa-#y{C&%6bk#2 z+6>$_6bb4ug6s&Ks&wthZZZBg$6FpF@IVFd|XwZV3YVYEZQzu$N{w6l}sPQK&yimz+KsXO;*vIVF-Ruo+D;Kx7IJ z%0%5QF$BO7oB`O=OWWILk302suL3=0@apsZyheZx9HQPL+MKpHk>%h8*$hu_t%3** zH-)m}{3dQtq(FdeOt}Lp`Z5{V9{TiL-&h1*?7&85@vryueg0@7&*w$RY`626`k|3Y8wH*_jdi1_naq;#}L*E!M) zaJpaWEpUkIA|Z+~fZ2}|gaNFv<;}2=uv4gk!P8>ijI$)Cq+!CxTde}s?0N+8m}_R9 z`vcM6r{Q-b(R>D3w4dm!;_T6N_#JIN1w(Qwixcd)QYj}DN4D6{*N5Zlb}Lf${O=L{afKZo zfOzk4tsquPC7$C>bG`rDZZ*)C5kaXShFPtUMxew-bm}G7swhpI5!fqp8g2X~;{h{YcA^=p)4i2Ud=lMRg|uz$(NdY!>d`NW-8B&63}T-N01 z0qaF1$WNyWL-*@1tjflLh&$g_{-KPa2ff}k%9wY2zGnxHq_4(A{NTe@${B^tg7Dr! zB^%lgU4ivBm3E@610V>0Sg|hOst7sp3}4k{tP^Y)J{zZ;$`!5>Zh40P$X}FaIaM=iHtRjh)O4IN4^Oj(>$og+==D+(3qqov&w) zwXYV_ueHQlY@tY5x1`9SHP(-x?W;FmaZ*2AFuT*0F#;bk3!^QGCE1XTfpaZ@<)OrcLm0cu`D)6IV4 z4_pm*K|Ve5|vO_T00jwF~FErL=L!qfK^1FNob2>u}jVMR}Y4#)h**8AVP1 zBIwJ|B?eH|NUyj)DSSZGoh zb-2}d4U;K5v}oVu6KsNFjN#Wa?H&&Mi+qR1zz^i9ItZ`F+7?v&o44|3j{oK@{PK>? zoUyD37%$x4Xz$yt`P!w5&KKi&b)uTR;2AFN!pwmrO7}^1#bb%b&}_)@ysaRFlyZsP zk18q@c@D8L(h?(5Cb3ah#Wp$E6dE8(W=eZ-1b=*i@4q^xE%H)?Y)4)wYDrA6qb6NM z8X$uxBiMCpOV~uJtbjHWf@JW3{qfT#kHFnH%lz09x<=n(C-=&C^M`$OC8~>OIhW8l z5sQ_*=OPW&Ua7E3Tue9@{us~u*!H=zO&}Zan+6S5M-)!-n8#kOjMmN5J_JFGwIg#R zWEV|Vat_(`1)PR3GKgP@)Rtb%=tFB*@R2!1DoO8nfahH(()$Wq-6&5g)bmr*x;t?N zj8)g?9cSm3lL2(trPWtG`~<0&-I7gW)CniuT^4E_MGPVSF8{5cbpz0TEbjExIZ1Hh zlKy;^mVBe~+fJ@_GWdCL4#ByrGL)iabde;@-56LcWStneI%fyGs z+Bh2ELUlespA;QQzE;^@Y*nN*HtYT4rX+08A~_`8oUJKYCmh-5y^|O90$(kj?N&l- zCfLcA)}{)_;leLPg9XN5L>pfH{HLX}@@+8SZ#KkFwmX8GmQxD=y9teR(>!-+8`#;m zIw&^EKhN%1A4WWRQChP306pBRIPLF!CHA$UY;s4G=Dgn}IPt=AyaEsCNMeKy`9=N; zIL1S>UUK&5%jIHaO{Jf?!?}wy;d7Hs`&qPogj7ietWm(WS}hak&5a6)5~&-x&WR5E zw<1{Rlj=Y^dAJ?B}+VUZu`PFka z`R>bZ;U>j!iOri!4_9C4Q(Y)O0<_L1@!P;keyHaxK+f8(zVm3S!oYpakcO5Wj~%>M zUR2S(f?ZZuOHv1(ao%R}N6OLZ!I*|mgOV1cU@$k&BL*VpDf$#7rG52xf(Tw|9dM8u z?)@N;YWqdawD_OKpS_Grt}2mPqnZSDNY9lMTZ6>gSb`E?=c8Z~e})F>Gtr5-efw%n zUoi0~(FS`n1w%EsItKxAS~UNvZOw73cpFaL=+m&A5Zaf-+xot8XRAB@C}ATv>cnO# z6vv%3L_Z4mY4eP(4pqNWOt(#qH4)M~KHa+-aZKJ^w?w@Mj>J%=-nBcv|K!Q}=!TumG$kY*z zs|a@LBk+aa#b1>hx@J&F5E};@CE$QIL&Wv7hJfDL= z>Xl?preJlv-H|rHjoj01|1Vn_rA882l*I5p9P*nkll3q)u8lewqV)p`9!qkj4Iz(S zhFDZp3FT;WZfa2fdfKuQnv?y$>)~$H9N+NAva&zYVBHl9@5=aHjO5L0QK{yeW-aIp z*6F(mX^PxFdq!g`?2pL^_QDI)9A6k4SsehI{+I9!pjewvx#bS6%~DGC)$Dz{4_m}$ z;sxw?)raO5&B>XxZiEHPPnbWXG^#LGhT?|^dT5JRP49qdaI|MeU6ak2h6mgY-0im^ zUg1s?w=&?-tHikAF4UlMg@GVJ>#qo;FnL9I5GUhk!9vcPO;!iP{IwXT1XRLB@TpOd z&Qj6}l8y4PJzxG;D@bkK*`4PP?_z-xV*shDWv$WmgnD&|5OL3fA5S~34! zM7TcEE{fwsroW+b^-mC;2vSO=mP&m}fZquZ*1_nPzwHQ9;M7RuBsld?)D`({M$sa4 z-YB{zk{0-IqZ%)KQf@yZO8r~^oA@Xd#7nFi&pNcFTk?+<(YCvTp|uk<+N4670`dBHfKLKy0w}oHIBc5Y+a%*z%>!ageTjHQjN^$@f3ITK)V3V<1WX>z+4z zFjG{od8tVYW|9|Gjfab6OLDx}k47>{@jxxC&GO!2=Ee8)AwnAz9Qi}Kob;YylK9$t z0`Jf9r?(y+)d)(=?_}k!2ih`Et{PsBezfYoq4VTz#;-p_PeQ8Wi5SK6Bw>VbHhHvX zN1LKdCFTo-Y)Sp$el}1?!Up{A>FQb7s3s)G;09l5m>Rk zU)gRQ5rG9O@($B~_F#J?ZynyURR1^T5EkEcdL!e{I86p?b~ze*3-#Mb6cL5xS*On& z?OOoT!q!nrV_HgsPaU< zUHR~fb60CD9H*r&cCgIJ_reGplT|pGJ)1eYBk|ptZ<;xx@24V9aNVMDDt2mV-P@|) zv_+WYgTps>GgvT_+Xd3z8m0E=HhK&rUc>pqJ1v+=rl%9d@SoyBnnkIOq|QqU*uFb4 z0Mb46M=EwleCazOH6L`3^Vn=ikGlacDSmzg{WW;;szG7S1AL)nr-}HZ;Tuq4h*##4 z+4gh7d>f>Px2rSUAo)04hcI9H<@(!;?f_tE@F?oy<4+YtEWzt=o#(bM?n#iQM+xos zv~R4h1;~z8eVCo>`X)#^QQ!BJ zy*>k^AdloYtCVu01|qD;y&x}KGEfNsWF_Hij-PyB;#Nice5wX+_&|3eHwku|0}PE5i5&f5tiT&s6F6x`+{X892V%AC4djOwoOGbetCYys5*=Trg-yNs4qVLb&>qUww-q@FHi!Gs$2~wTMc^e$)%CGLZ!{de zI3B~)luAA>53;XufS@Y@QC{DpcU!u~k5mU+voOe4|Hi-?ya1j@gZgzZb&0(!PK1C_FG{-IJ;(e-3+$vSMSJJShS((Bn<7-XCJU`U`&{0Ak@OKSgSlpbEjSM!ZtQ&}ZxEylbScxTj9t<_^s|8juogce1XlKd=E z^du}lZ`Pw+%I*nURp8}R;~Uv53sAz3v;~v4q!kClG)$@r`9GPl2^zd6M8WFi~-koX3T%;~?mc#0~9AR|`Osvg{bv7Zdi zZJR2=B4XEf`$BtkQAbYnS!%ph=u6m&Md#2kl7S+3=FUDVv;Cvn>UQl>#`o!-dAcjH zlDPluk0|aDVxMLGQH#H}h*&vo5h4XY9;CO`iCMHtu;`1ZQe+$@wwsdvBM#wtsdEQF z5-FzY?EaA~aYnqx<_Fd{-IlAc%_vy28QXI;kj=BIGQ}-bW(OI7fH!3-qclULsq^@J z!OSxfdt78P*l2tqmWaK<@TNq9MK7OT3(f^6PY8S2eWW_pbp5s2z}t+}A0u=TG8-&2 zuj6BM$1BUmEr~TKGq|O7GUoCD$(%KfTV+Y`1#QbHU6~&r1jHN=D%30Ka6@4HWW*(Q4{P8D>SdJNQ_Do zj+QB&rH_!~K#N)qB^Iqx+N`QZg4d(5##~84(;NjMX`hT(>poAqy~26O-apCRZh#&R zI;pM1I?O_E+ecEbU#eNp^kA=>L{6_@1j(C;_FoS%5HB$G+4{k58`_R+d^qx`Sk0ne z#rq&_(hu+}mr0#-0Z)&mpC>sGb?|0S+&sm)FLuam?t3n9*Y-Rtvv}!yn`wRuS{A19 z{ro)v&}HdQ3*#X`BTRg{rwbP+t%cx(7&@736u$8~I2q0r?x4=RD15Qu6bnJdD8#cR z+#otWJ?bw#Ef60&QZ2^1pYEr2V&@h6^z-E#+gLanor(BUQoMN#oX7tZzb7nazi+Uo zNBy#LY+_`NXhiJAq(XYLI8$-96K;$iGi2@?>iD-566YOeWHoR4e>JI9E2OoYCi9Su zDP-3#@Uj<3NPx|;Yfs27iBc*~M;fNtXRMn0vQdJfMkFym5yH=zt_Hc4jsscwSkEKc zuZafF45o!t0puLKu@+4g=lE-aqy=7&V3*EvY2|N)YzmV0ABJwaA??Ty@@?^miFd@_ zoR0H4OA*LxWVarcE zqNZwy)FTA16OuNI6ZY@_qED(%+}i-Qa-$SCw^_}NdF#R$MXbK*dCG@Al>7GF5ZzAv9=xR%0JFW_?8TsuR>c00@)-%UAMO*}f9lcm z7~6$-3G<@ovF)@gur4t<)DhCrZFlapMEGtF%~1RfyyZE7j__BXg4hfPqzX=t)8!6T z-g*+a@Gcu)29>k$e(<&)&l+U(>uF6#RgB!wV8*UO)0L|ur!yBJKN<}Z|H^I#-|}8O zS2W&&IOOUZJuixF=0&;1n^S@fHX4YU#8zzf;RNsc&D!;9kO9@sn=@Ok`_$18NS3X) zSv{)Z2#T}x1TzNy_hmiA%e-v%m?sCXgkR0WLDq65$Xb@CGKdGo}^pa-Y-j~6wf?guih{76N4LBin-7) z4WFo2JwzHnQk&_IPnLgRPeX#)aS_-`X~~Rrj=BqU9-kjBk*~M zs%378-Ue&6T7 z|L~fQ#!&>w`OeK|^8=aXX$w#~AvqZ2aLc106d_V*gssBN!mITQhBe?WX)A0xBf&d9 zo-lfIa?<~VPas}G60tFGzf+)a3eVa?$PQFC#5VB9!#qSRq@f}5bG9-Ve>wN9FyA;T zBh)r$;!cT}1&D*i4O^~!z0Qn%$fX0b4i^tbObh~>f>>S584DraBm{Nte9nafS+!B> zP$#v5{#)S16EA0t3~;eI_|JIpzd!SbpOq&f?CQWgYw1z*_&t+F=#xaCFuCU7OD80kh6KJt#x; ziB6tuIS{2RPp1@)KW=`@|JwL!-YjzABx?J=c<^2>I@s%+*o7{c&48I;pg?f<7T(B8 z;YxmBz$m7$PX$P-Zg^*KICjKWWAe~6jw&C@d88M4M0i*(jZgk0%8z1C%Eahs^BYXZ z@Q1Cwtaa5}WKk(SJvc@@Ik7c&lzI=;I-2Y3@m(LPJ9+@4K4aV#byAuuAAb!qWVtwb z(a|IfB78n`ZCC;2ND_W5zc*|5;Q_k4!@IzKdu036Zz1Pa0UM92hk1v+$%}gS)C!O| zolq_CmgFol3^tUgyXjByC&m-J!Zf<=D{5ZP>LLaT^hX-lzRDt<4=)&>_Q9su ziY-6<^ojVCz|_TF=x6|d=dL@)tqjW5X*Vbulsj`3lI9|JYo`7+ip*Y~EhQFRUXIa0 zSmnjQoK#9aG9l!cghl|2`~z}

      M(0kd4z=c*kL!x3F%y{f-R~s~fQFuCQBA=g^JH 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�*p`7ObTrIq}?Ie)qO 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 literal 0 HcmV?d00001 diff --git a/frontend/src/pages/MainPage/MainPage.tsx b/frontend/src/pages/MainPage/MainPage.tsx index ce6578ad..fb9de91b 100644 --- a/frontend/src/pages/MainPage/MainPage.tsx +++ b/frontend/src/pages/MainPage/MainPage.tsx @@ -1,30 +1,20 @@ -import { useNavigate } from 'react-router-dom'; -import { useSetRecoilState } from 'recoil'; - import { mainPageLayout, logoWrapper, title, intro } from './MainPage.styled'; +import { useCreateRoom } from './useCreateRoom'; +import logoIcon from '@/assets/images/logoIcon.png'; import Button from '@/components/common/Button/Button'; -import { memberInfoState } from '@/recoil/atom'; const MainPage = () => { - const navigate = useNavigate(); - const setMemberInfo = useSetRecoilState(memberInfoState); - - const goToNicknamePage = () => { - navigate('/nickname'); - }; - - const handleClick = () => { - goToNicknamePage(); - setMemberInfo((memberInfo) => ({ ...memberInfo, isMaster: true })); - }; + const { handleRoomCreate } = useCreateRoom(); return (

      -
      LO to the GO
      +
      + 로고 아이콘 +

      땅콩

      어색한 분위기를 주도해봐요

      - +
      ); }; diff --git a/frontend/src/pages/MainPage/useCreateRoom.ts b/frontend/src/pages/MainPage/useCreateRoom.ts new file mode 100644 index 00000000..fa6ad3bd --- /dev/null +++ b/frontend/src/pages/MainPage/useCreateRoom.ts @@ -0,0 +1,20 @@ +import { useNavigate } from 'react-router-dom'; +import { useSetRecoilState } from 'recoil'; + +import { memberInfoState } from '@/recoil/atom'; + +export const useCreateRoom = () => { + const navigate = useNavigate(); + const setMemberInfo = useSetRecoilState(memberInfoState); + + const goToNicknamePage = () => { + navigate('/nickname'); + }; + + const handleRoomCreate = () => { + goToNicknamePage(); + setMemberInfo((memberInfo) => ({ ...memberInfo, isMaster: true })); + }; + + return { handleRoomCreate }; +}; From b8ad0ec1d5b011684d4776fb930ff53ac26d5f50 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Fri, 2 Aug 2024 15:37:31 +0900 Subject: [PATCH 0457/1013] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=ED=8C=8C=EC=9D=BC=20=EC=A0=9C=EA=B1=B0=20?= =?UTF-8?q?#92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/mocks/handlers/roomHandler.ts | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 frontend/src/mocks/handlers/roomHandler.ts diff --git a/frontend/src/mocks/handlers/roomHandler.ts b/frontend/src/mocks/handlers/roomHandler.ts deleted file mode 100644 index 3bc693d0..00000000 --- a/frontend/src/mocks/handlers/roomHandler.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { http, HttpResponse } from 'msw'; - -// import ROOM_AND_MEMBER from '../data/RoomInfo.json'; -import ROOM_MEMBERS from '../data/roomMembers.json'; - -import { MOCK_API_URL } from '@/constants/url'; -import { RoomMembers } from '@/types/room'; - -export const roomHandler = [ - // http.get(MOCK_API_URL.roomMembers, () => HttpResponse.json(ROOM_MEMBERS)), -]; From 2d486cb28120a1ac397f13d01442735feb420607 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Fri, 2 Aug 2024 15:39:47 +0900 Subject: [PATCH 0458/1013] =?UTF-8?q?fix:=20=EC=9D=98=EB=8F=84=EC=B9=98=20?= =?UTF-8?q?=EC=95=8A=EC=9D=80=20indent=EB=A1=9C=20=EB=AA=A9=EC=B0=A8?= =?UTF-8?q?=EC=97=90=20=EB=B0=98=EC=98=81=EB=90=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0=20#58?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/docs/asciidoc/room.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/docs/asciidoc/room.adoc b/backend/src/docs/asciidoc/room.adoc index 52f8da60..97f64b30 100644 --- a/backend/src/docs/asciidoc/room.adoc +++ b/backend/src/docs/asciidoc/room.adoc @@ -102,7 +102,7 @@ response fields include::{snippets}/room/next/response-fields.adoc[] - === 라운드 종료 여부 +=== 라운드 종료 여부 ==== curl From 5f5f927816a6d32ac67861d2664c5e0f02ca02ff Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Fri, 2 Aug 2024 15:46:23 +0900 Subject: [PATCH 0459/1013] =?UTF-8?q?chore:=20cd=20deploy=20job=20?= =?UTF-8?q?=EC=8B=9C=EA=B0=84=EC=A0=9C=ED=95=9C=202=EB=B6=84=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=A1=B0=EC=A0=95=20#116?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 40cfee34..fc80a9bd 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -55,7 +55,7 @@ jobs: deploy: needs: build - timeout-minutes: 1 + timeout-minutes: 2 runs-on: [ self-hosted, linux, ARM64 ] # Self hosted runner 사용 env: DOCKER_REPOSITORY_NAME: ddangkong/ddangkong-api-dev From 7c4892e9fe099069df4a4086f1eddc86bb25c180 Mon Sep 17 00:00:00 2001 From: jhon3242 Date: Fri, 2 Aug 2024 15:47:52 +0900 Subject: [PATCH 0460/1013] =?UTF-8?q?feat:=20=EC=A3=BC=EC=A0=9C,=20?= =?UTF-8?q?=EC=84=A0=ED=83=9D=EC=8B=9C=20=EC=A1=B0=ED=9A=8C=20=EC=8B=9C=20?= =?UTF-8?q?=EB=B0=A9=20=EC=83=81=ED=83=9C=20=EA=B2=80=EC=A6=9D=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20=EC=9D=91=EB=8B=B5=EA=B0=92=EC=97=90=20?= =?UTF-8?q?=EC=A0=9C=ED=95=9C=EC=8B=9C=EA=B0=84=20=EC=B6=94=EA=B0=80=20#11?= =?UTF-8?q?3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/dto/BalanceContentResponse.java | 2 ++ .../content/BalanceContentService.java | 12 ++++++++-- .../content/BalanceContentControllerTest.java | 7 +++++- .../balance/room/RoomControllerTest.java | 7 +++++- .../BalanceContentDocumentationTest.java | 10 +++++++- .../balance/room/RoomDocumentationTest.java | 2 ++ .../content/BalanceContentServiceTest.java | 23 ++++++++++++++++++- .../service/balance/room/RoomServiceTest.java | 13 +++++++---- backend/src/test/resources/init-test.sql | 8 +++++-- 9 files changed, 72 insertions(+), 12 deletions(-) diff --git a/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentResponse.java b/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentResponse.java index de7c43b9..1d70803c 100644 --- a/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentResponse.java +++ b/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentResponse.java @@ -11,6 +11,7 @@ public record BalanceContentResponse( Category category, int totalRound, int currentRound, + int timeLimit, String question, BalanceOptionResponse firstOption, BalanceOptionResponse secondOption @@ -23,6 +24,7 @@ private BalanceContentResponse(RoomContent roomContent, roomContent.getContentCategory(), roomContent.getTotalRound(), roomContent.getRound(), + roomContent.getRoom().getTimeLimit(), roomContent.getContentName(), BalanceOptionResponse.from(balanceOptions.getFistOption()), BalanceOptionResponse.from(balanceOptions.getSecondOption())); diff --git a/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java b/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java index 81b63f1a..cce442a9 100644 --- a/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java +++ b/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java @@ -24,7 +24,8 @@ public class BalanceContentService { @Transactional(readOnly = true) public BalanceContentResponse findRecentBalanceContent(Long roomId) { - RoomContent roomContent = findCurrentRoomContent(roomId); + Room room = findProgessingRoom(roomId); + RoomContent roomContent = findCurrentRoomContent(room); BalanceOptions balanceOptions = balanceOptionRepository.getBalanceOptionsByBalanceContent( roomContent.getBalanceContent()); @@ -34,8 +35,15 @@ public BalanceContentResponse findRecentBalanceContent(Long roomId) { .build(); } - private RoomContent findCurrentRoomContent(Long roomId) { + private Room findProgessingRoom(Long roomId) { Room room = roomRepository.getById(roomId); + if (!room.isGameProgress()) { + throw new BadRequestException("해당 방은 게임을 진행하고 있지 않습니다."); + } + return room; + } + + private RoomContent findCurrentRoomContent(Room room) { return roomContentRepository.findByRoomAndRound(room, room.getCurrentRound()) .orElseThrow(() -> new BadRequestException("해당 방의 현재 진행중인 질문이 존재하지 않습니다.")); } diff --git a/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java index 26807b5c..9e264f26 100644 --- a/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java @@ -16,7 +16,12 @@ class BalanceContentControllerTest extends BaseControllerTest { class 현재_방의_내용_조회 { private static final BalanceContentResponse EXPECTED_RESPONSE = new BalanceContentResponse( - 1L, Category.EXAMPLE, 5, 2, "민초 vs 반민초", + 1L, + Category.EXAMPLE, + 5, + 2, + 30_000, // TODO 추후 sec으로 변경 + "민초 vs 반민초", new BalanceOptionResponse(1L, "민초"), new BalanceOptionResponse(2L, "반민초")); diff --git a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java index 3e0f0150..e803bf75 100644 --- a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java @@ -125,7 +125,12 @@ class 방_참가 { class 다음_라운드_진행 { private static final BalanceContentResponse EXPECTED_RESPONSE = new BalanceContentResponse( - 3L, Category.EXAMPLE, 5, 3, "다음 중 여행가고 싶은 곳은?", + 3L, + Category.EXAMPLE, + 5, + 3, + 30_000, // TODO 추후 sec으로 변경 + "다음 중 여행가고 싶은 곳은?", new BalanceOptionResponse(5L, "산"), new BalanceOptionResponse(6L, "바다")); diff --git a/backend/src/test/java/ddangkong/documentation/balance/content/BalanceContentDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/content/BalanceContentDocumentationTest.java index e05c84b3..0546f6ee 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/content/BalanceContentDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/content/BalanceContentDocumentationTest.java @@ -40,7 +40,14 @@ class 방의_콘텐츠_조회 { BalanceOptionResponse firstOptionResponse = new BalanceOptionResponse(1L, "100억 빚 송강"); BalanceOptionResponse secondOptionResponse = new BalanceOptionResponse(2L, "100억 부자 송강호"); BalanceContentResponse response = new BalanceContentResponse( - 1L, Category.EXAMPLE, 5, 2, "100억 빚 송강 vs 100억 부자 송강호", firstOptionResponse, secondOptionResponse + 1L, + Category.EXAMPLE, + 5, + 2, + 30_000, // TODO sec 단위로 수정 + "100억 빚 송강 vs 100억 부자 송강호", + firstOptionResponse, + secondOptionResponse ); when(balanceContentService.findRecentBalanceContent(anyLong())).thenReturn(response); @@ -57,6 +64,7 @@ class 방의_콘텐츠_조회 { fieldWithPath("category").type(STRING).description("콘텐츠 카테고리"), fieldWithPath("totalRound").type(NUMBER).description("총 라운드 수"), fieldWithPath("currentRound").type(NUMBER).description("현재 라운드"), + fieldWithPath("timeLimit").type(NUMBER).description("라운드 제한시간"), fieldWithPath("question").type(STRING).description("콘텐츠 질문"), fieldWithPath("firstOption.optionId").type(NUMBER).description("첫 번째 선택지 ID"), fieldWithPath("firstOption.name").type(STRING).description("첫 번째 선택지명"), diff --git a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java index 5680266a..073f99ba 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java @@ -175,6 +175,7 @@ class 다음_라운드로_이동 { Category.EXAMPLE, 5, 2, + 30_000, // TODO sec 단위로 수정 "10년 동안 한 사람과 연애한 애인 VS 1년 동안 다섯 사람과 연애한 애인", firstOption, secondOption @@ -195,6 +196,7 @@ class 다음_라운드로_이동 { fieldWithPath("category").type(STRING).description("콘텐츠 카테고리"), fieldWithPath("totalRound").type(NUMBER).description("총 라운드 수"), fieldWithPath("currentRound").type(NUMBER).description("현재 라운드"), + fieldWithPath("timeLimit").type(NUMBER).description("라운드 제한시간"), fieldWithPath("question").type(STRING).description("콘텐츠 질문"), fieldWithPath("firstOption.optionId").type(NUMBER).description("첫 번째 선택지 ID"), fieldWithPath("firstOption.name").type(STRING).description("첫 번째 선택지명"), diff --git a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java index f938baa1..f9178036 100644 --- a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertAll; import ddangkong.controller.balance.content.dto.BalanceContentResponse; import ddangkong.controller.balance.option.dto.BalanceOptionResponse; @@ -23,8 +24,15 @@ class 현재_방의_밸런스_게임_내용_조회 { private static final Long PROGRESS_ROOM_ID = 1L; private static final Long NOT_EXIST_ROOM_ID = 99999999L; private static final Long NOT_PROGRESSED_ROOM_ID = 2L; + private static final Long READY_ROOM_ID = 4L; + private static final Long FINISHED_ROOM_ID = 5L; private static final BalanceContentResponse BALANCE_CONTENT_RESPONSE = new BalanceContentResponse( - 1L, Category.EXAMPLE, 5, 2, "민초 vs 반민초", + 1L, + Category.EXAMPLE, + 5, + 2, + 30_000, // TODO 추후 sec으로 변경 + "민초 vs 반민초", new BalanceOptionResponse(1L, "민초"), new BalanceOptionResponse(2L, "반민초")); @@ -52,5 +60,18 @@ class 현재_방의_밸런스_게임_내용_조회 { .isInstanceOf(BadRequestException.class) .hasMessage("해당 방의 현재 진행중인 질문이 존재하지 않습니다."); } + + @Test + void 방의_상태가_진행중이_아닌_경우_예외를_던진다() { + // when & then + assertAll( + () -> assertThatThrownBy(() -> balanceContentService.findRecentBalanceContent(READY_ROOM_ID)) + .isInstanceOf(BadRequestException.class) + .hasMessage("해당 방은 게임을 진행하고 있지 않습니다."), + () -> assertThatThrownBy(() -> balanceContentService.findRecentBalanceContent(FINISHED_ROOM_ID)) + .isInstanceOf(BadRequestException.class) + .hasMessage("해당 방은 게임을 진행하고 있지 않습니다.") + ); + } } } diff --git a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java index f42a10d8..5770f8ab 100644 --- a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java @@ -55,8 +55,8 @@ class 방_생성 { void 방_생성_시_방장_멤버를_생성하고_방을_생성한다() { // given String nickname = "나는방장"; - MemberResponse expectedMemberResponse = new MemberResponse(7L, nickname, true); - RoomJoinResponse expected = new RoomJoinResponse(4L, expectedMemberResponse); + MemberResponse expectedMemberResponse = new MemberResponse(9L, nickname, true); + RoomJoinResponse expected = new RoomJoinResponse(6L, expectedMemberResponse); // when RoomJoinResponse actual = roomService.createRoom(nickname); @@ -74,7 +74,7 @@ class 방_참여 { // given String nickname = "나는참가자"; Long joinRoomId = 2L; - MemberResponse expectedMemberResponse = new MemberResponse(7L, nickname, false); + MemberResponse expectedMemberResponse = new MemberResponse(9L, nickname, false); RoomJoinResponse expected = new RoomJoinResponse(joinRoomId, expectedMemberResponse); // when @@ -103,7 +103,12 @@ class 다음_라운드로_이동 { private static final Long NOT_EXIST_ROOM_ID = 999999999L; private static final Long NOT_PROGRESSED_ROOM_ID = 2L; private static final BalanceContentResponse BALANCE_CONTENT_RESPONSE = new BalanceContentResponse( - 3L, Category.EXAMPLE, 5, 3, "다음 중 여행가고 싶은 곳은?", + 3L, + Category.EXAMPLE, + 5, + 3, + 30_000, // TODO 추후 sec으로 변경 + "다음 중 여행가고 싶은 곳은?", new BalanceOptionResponse(5L, "산"), new BalanceOptionResponse(6L, "바다")); diff --git a/backend/src/test/resources/init-test.sql b/backend/src/test/resources/init-test.sql index 39b7dfe2..c806f710 100644 --- a/backend/src/test/resources/init-test.sql +++ b/backend/src/test/resources/init-test.sql @@ -1,7 +1,9 @@ INSERT INTO room (total_round, current_round, time_limit, status, category) VALUES (5, 2, 30000, 'PROGRESS', 'EXAMPLE'), (5, 1, 30000, 'PROGRESS', 'EXAMPLE'), - (5, 1, 30000, 'PROGRESS', 'EXAMPLE'); + (5, 1, 30000, 'PROGRESS', 'EXAMPLE'), + (3, 1, 30000, 'READY', 'EXAMPLE'), + (3, 1, 30000, 'FINISH', 'EXAMPLE'); INSERT INTO member (nickname, room_id, is_master) VALUES ('mohamedeu al katan', 1, true), @@ -9,7 +11,9 @@ VALUES ('mohamedeu al katan', 1, true), ('rupi', 1, false), ('rapper lee', 1, false), ('alpha', 2, true), - ('bravo', 2, false); + ('bravo', 2, false), + ('ready player', 4, true), + ('finish player', 5, true); INSERT INTO balance_content (category, name) VALUES ('EXAMPLE', '민초 vs 반민초'), From e81bc452747d9fa99232190240744a760b4ff5fe Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Fri, 2 Aug 2024 15:48:35 +0900 Subject: [PATCH 0461/1013] =?UTF-8?q?test:=20=ED=98=84=EC=9E=AC=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B4=EB=93=9C=EA=B0=80=20=EB=81=9D=EB=82=AC?= =?UTF-8?q?=EB=8A=94=EC=A7=80=20=EC=97=AC=EB=B6=80=20=ED=99=95=EC=9D=B8?= =?UTF-8?q?=ED=95=98=EB=8A=94=20msw=20=EA=B5=AC=ED=98=84=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/constants/url.ts | 3 +++ frontend/src/mocks/data/roundVoteIsFinished.json | 3 +++ .../src/mocks/handlers/balanceContentHandler.ts | 14 +++++++++++++- 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 frontend/src/mocks/data/roundVoteIsFinished.json diff --git a/frontend/src/constants/url.ts b/frontend/src/constants/url.ts index ca92cbf3..0b763cc9 100644 --- a/frontend/src/constants/url.ts +++ b/frontend/src/constants/url.ts @@ -8,6 +8,8 @@ export const API_URL = { `${BASE_URL}/api/balances/rooms/${roomId}/contents/${contentId}/vote-result`, moveNextRound: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/contents`, finalResult: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/final`, + roundVoteIsFinished: (roomId: number, contentId: number) => + `${BASE_URL}/api/balances/rooms/${roomId}/contents/${contentId}/vote-finished`, }; export const MOCK_API_URL = { @@ -16,4 +18,5 @@ export const MOCK_API_URL = { roundVoteResult: '/api/balances/rooms/:roomId/contents/:contentId/vote-result', moveNextRound: '/api/balances/rooms/:roomId/contents', finalResult: '/api/balances/rooms/:roomId/final', + roundVoteIsFinished: 'api/balances/rooms/:roomId/contents/:contentId/vote-finished', }; diff --git a/frontend/src/mocks/data/roundVoteIsFinished.json b/frontend/src/mocks/data/roundVoteIsFinished.json new file mode 100644 index 00000000..bd784660 --- /dev/null +++ b/frontend/src/mocks/data/roundVoteIsFinished.json @@ -0,0 +1,3 @@ +{ + "finished": false +} diff --git a/frontend/src/mocks/handlers/balanceContentHandler.ts b/frontend/src/mocks/handlers/balanceContentHandler.ts index a7ecd3ae..347ea961 100644 --- a/frontend/src/mocks/handlers/balanceContentHandler.ts +++ b/frontend/src/mocks/handlers/balanceContentHandler.ts @@ -1,6 +1,7 @@ import { http, HttpResponse } from 'msw'; import BALANCE_CONTENT from '../data/balanceContent.json'; +import ROUND_VOTE_IS_FINISHED from '../data/roundVoteIsFinished.json'; import { MOCK_API_URL } from '@/constants/url'; import { BalanceContent } from '@/types/balanceContent'; @@ -9,4 +10,15 @@ const fetchBalanceContentHandler = () => { return HttpResponse.json(BALANCE_CONTENT); }; -export const contentHandler = [http.get(MOCK_API_URL.balanceContent, fetchBalanceContentHandler)]; +const fetchIsFinishedHandler = () => { + setTimeout(() => { + ROUND_VOTE_IS_FINISHED.finished = true; + }, 17 * 1000); + + return HttpResponse.json(ROUND_VOTE_IS_FINISHED); +}; + +export const contentHandler = [ + http.get(MOCK_API_URL.balanceContent, fetchBalanceContentHandler), + http.get(MOCK_API_URL.roundVoteIsFinished, fetchIsFinishedHandler), +]; From 5c42509fe2615a64ba4960324b40ddd42d946d20 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Fri, 2 Aug 2024 15:53:26 +0900 Subject: [PATCH 0462/1013] =?UTF-8?q?feat:=20=EB=9E=9C=EB=8D=A4=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=BB=A8=ED=85=90=EC=B8=A0=EB=A5=BC=20N=EA=B0=9C?= =?UTF-8?q?=20=EC=A1=B0=ED=9A=8C=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20#99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/BalanceContentRepository.java | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/content/BalanceContentRepository.java b/backend/src/main/java/ddangkong/domain/balance/content/BalanceContentRepository.java index 5ed28c7d..347bfeca 100644 --- a/backend/src/main/java/ddangkong/domain/balance/content/BalanceContentRepository.java +++ b/backend/src/main/java/ddangkong/domain/balance/content/BalanceContentRepository.java @@ -1,13 +1,33 @@ package ddangkong.domain.balance.content; -import ddangkong.domain.balance.option.BalanceOption; +import static java.util.stream.Collectors.toList; + import ddangkong.exception.BadRequestException; +import ddangkong.exception.InternalServerException; +import java.util.Collections; +import java.util.List; +import java.util.stream.LongStream; import org.springframework.data.jpa.repository.JpaRepository; public interface BalanceContentRepository extends JpaRepository { + long count(); + + List findByIdIn(List ids); + default BalanceContent getById(Long id) { return findById(id) .orElseThrow(() -> new BadRequestException("해당 질문 컨텐츠가 존재하지 않습니다.")); } + + default List findByRandom(int count) { + List ids = LongStream.rangeClosed(1, count).boxed().collect(toList()); + if (ids.size() < count) { + throw new InternalServerException("질문이 라운드만큼 존재하지 않습니다."); + } + + Collections.shuffle(ids); + List candidateIds = ids.subList(0, count); + return findByIdIn(candidateIds); + } } From 1709255587ffae5468ca4787548a36419ef8d89b Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Fri, 2 Aug 2024 15:57:02 +0900 Subject: [PATCH 0463/1013] =?UTF-8?q?feat:=20=EA=B2=8C=EC=9E=84=20?= =?UTF-8?q?=EC=8B=9C=EC=9E=91=20=EC=8B=9C,=20=ED=95=B4=EB=8B=B9=20?= =?UTF-8?q?=EB=B0=A9=EC=9D=98=20=EC=BB=A8=ED=85=90=EC=B8=A0=EB=A5=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/balance/room/RoomService.java | 32 ++++++++------ .../service/balance/room/RoomServiceTest.java | 44 ++++++++++++++++++- backend/src/test/resources/init-test.sql | 27 ++++++++---- 3 files changed, 78 insertions(+), 25 deletions(-) diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index 58404cd8..69fca4ad 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -5,6 +5,7 @@ import ddangkong.controller.balance.room.dto.RoomInfoResponse; import ddangkong.controller.balance.room.dto.RoomJoinResponse; import ddangkong.domain.balance.content.BalanceContent; +import ddangkong.domain.balance.content.BalanceContentRepository; import ddangkong.domain.balance.option.BalanceOptionRepository; import ddangkong.domain.balance.option.BalanceOptions; import ddangkong.domain.balance.room.Room; @@ -29,6 +30,8 @@ public class RoomService { private final RoomContentRepository roomContentRepository; + private final BalanceContentRepository balanceContentRepository; + private final BalanceOptionRepository balanceOptionRepository; @Transactional(readOnly = true) @@ -53,6 +56,21 @@ public RoomJoinResponse joinRoom(String nickname, Long roomId) { return new RoomJoinResponse(room.getId(), new MemberResponse(member)); } + @Transactional + public void startGame(Long roomId) { + Room room = roomRepository.getById(roomId); + room.startGame(); + + List balanceContents = balanceContentRepository.findByRandom(room.getTotalRound()); + List roomContents = RoomContent.createList(room, balanceContents); + startRound(roomContents.get(0)); + roomContentRepository.saveAll(roomContents); + } + + private void startRound(RoomContent roomContent) { + // TODO #109 머지 시 반영 + } + @Transactional public BalanceContentResponse moveToNextRound(Long roomId) { Room room = roomRepository.getById(roomId); @@ -71,18 +89,4 @@ private RoomContent findCurrentRoomContent(Room room) { return roomContentRepository.findByRoomAndRound(room, room.getCurrentRound()) .orElseThrow(() -> new BadRequestException("해당 방의 현재 진행중인 질문이 존재하지 않습니다.")); } - - @Transactional - public void startGame(Long roomId) { - Room room = roomRepository.getById(roomId); - room.startGame(); - - List balanceContents = findContents(room); - List roomContents = RoomContent.createList(room, balanceContents); - roomContentRepository.saveAll(roomContents); - } - - private List findContents(Room room) { - return List.of(); // TODO 랜덤 N개 조회 로직 구현 - } } diff --git a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java index 374e1852..46ac51af 100644 --- a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java @@ -10,6 +10,9 @@ import ddangkong.controller.balance.room.dto.RoomInfoResponse; import ddangkong.controller.balance.room.dto.RoomJoinResponse; import ddangkong.domain.balance.content.Category; +import ddangkong.domain.balance.room.Room; +import ddangkong.domain.balance.room.RoomContentRepository; +import ddangkong.domain.balance.room.RoomRepository; import ddangkong.exception.BadRequestException; import ddangkong.service.BaseServiceTest; import org.assertj.core.api.Assertions; @@ -22,6 +25,12 @@ class RoomServiceTest extends BaseServiceTest { @Autowired private RoomService roomService; + @Autowired + private RoomRepository roomRepository; + + @Autowired + private RoomContentRepository roomContentRepository; + @Nested class 게임_방_정보_조회 { @@ -51,7 +60,7 @@ class 방_생성 { void 방_생성_시_방장_멤버를_생성하고_방을_생성한다() { // given String nickname = "나는방장"; - MemberResponse expectedMemberResponse = new MemberResponse(7L, nickname, true); + MemberResponse expectedMemberResponse = new MemberResponse(10L, nickname, true); RoomJoinResponse expected = new RoomJoinResponse(4L, expectedMemberResponse); // when @@ -70,7 +79,7 @@ class 방_참여 { // given String nickname = "나는참가자"; Long joinRoomId = 2L; - MemberResponse expectedMemberResponse = new MemberResponse(7L, nickname, false); + MemberResponse expectedMemberResponse = new MemberResponse(10L, nickname, false); RoomJoinResponse expected = new RoomJoinResponse(joinRoomId, expectedMemberResponse); // when @@ -92,6 +101,37 @@ class 방_참여 { } } + @Nested + class 게임_시작 { + + private static final Long READY_ROOM_ID = 3L; + + @Test + void 게임_시작_시_방이_진행_상태가_된다() { + // when + roomService.startGame(READY_ROOM_ID); + + // then + Room room = roomRepository.getById(READY_ROOM_ID); + assertThat(room.isGameProgress()).isTrue(); + } + + @Test + void 게임_시작_시_해당_방의_컨텐츠가_생성된다() { + // given + long beforeRoomContentCount = roomContentRepository.count(); + + // when + roomService.startGame(READY_ROOM_ID); + + // then + Room room = roomRepository.getById(READY_ROOM_ID); + long afterRoomContentCount = roomContentRepository.count(); + long addedRoomContentCount = afterRoomContentCount - beforeRoomContentCount; + assertThat(addedRoomContentCount).isEqualTo(room.getTotalRound()); + } + } + @Nested class 다음_라운드로_이동 { diff --git a/backend/src/test/resources/init-test.sql b/backend/src/test/resources/init-test.sql index f874c45a..80294679 100644 --- a/backend/src/test/resources/init-test.sql +++ b/backend/src/test/resources/init-test.sql @@ -1,7 +1,7 @@ INSERT INTO room (total_round, current_round, time_limit, status) VALUES (5, 2, 30000, 'PROGRESS'), (5, 1, 30000, 'PROGRESS'), - (5, 1, 30000, 'PROGRESS'); + (5, 1, 30000, 'READY'); INSERT INTO member (nickname, room_id, is_master) VALUES ('mohamedeu al katan', 1, true), @@ -9,18 +9,23 @@ VALUES ('mohamedeu al katan', 1, true), ('rupi', 1, false), ('rapper lee', 1, false), ('alpha', 2, true), - ('bravo', 2, false); + ('bravo', 2, false), + ('sunday', 3, true), + ('maru', 3, false), + ('pomae', 3, false); INSERT INTO balance_content (category, name) VALUES ('EXAMPLE', '민초 vs 반민초'), ('EXAMPLE', '월 200 백수 vs 월 500 직장인'), - ('EXAMPLE', '다음 중 여행가고 싶은 곳은?'); + ('EXAMPLE', '다음 중 여행가고 싶은 곳은?'), + ('EXAMPLE', '팔만대장경 다 읽기 vs 대장내시경 팔만번 하기'), + ('EXAMPLE', '개구리 맛 초콜릿 vs 초콜릿 맛 개구리'); -INSERT INTO room_content (room_id, balance_content_id, round, created_at) -VALUES (1, 2, 1, '2024-07-18 19:50:00.000'), - (1, 1, 2, '2024-07-18 20:00:00.000'), - (1, 3, 3, '2024-07-18 20:00:00.000'), - (3, 1, 1, '2024-07-18 19:51:00.000'); +INSERT INTO room_content (room_id, balance_content_id, round, created_at, round_ended_at, is_used) +VALUES (1, 2, 1, '2024-07-18 19:50:00.000', '2024-07-18 19:50:32.000', false), + (1, 1, 2, '2024-07-18 19:50:00.000', '2024-07-18 20:00:32.000', false), + (1, 3, 3, '2024-07-18 19:50:00.000', null, false), + (3, 1, 1, '2024-07-18 20:00:00.000', '2024-07-18 20:00:32.000', false); INSERT INTO balance_option (name, balance_content_id) VALUES ('민초', 1), @@ -28,7 +33,11 @@ VALUES ('민초', 1), ('월 200 백수', 2), ('월 200 직장인', 2), ('산', 3), - ('바다', 3); + ('바다', 3), + ('팔만대장경 다 읽기', 4), + ('대장내시경 팔만번 하기', 4), + ('개구리 맛 초콜릿', 5), + ('초콜릿 맛 개구리', 5); INSERT INTO balance_vote (balance_option_id, member_id) VALUES (4, 1), From b5725f707aca11fd544974bc9638865959bf40df Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Fri, 2 Aug 2024 16:03:24 +0900 Subject: [PATCH 0464/1013] =?UTF-8?q?feat:=20=EC=9E=84=EC=8B=9C=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=20=EB=B0=8F=20=EB=9D=BC=EC=9A=B4=EB=93=9C=20?= =?UTF-8?q?=EC=A2=85=EB=A3=8C=20=EC=97=AC=EB=B6=80=20=ED=99=95=EC=9D=B8=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80=20#58?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ddangkong/domain/balance/room/RoomContent.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java index 22ab7f88..0fa1236e 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java @@ -11,6 +11,7 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; +import java.time.LocalDateTime; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -35,6 +36,11 @@ public class RoomContent extends BaseEntity { @Column(nullable = false) private int round; + private LocalDateTime roundEndedAt; + + @Column(nullable = false) + private boolean isUsed; + public Long getContentId() { return balanceContent.getId(); } @@ -50,4 +56,8 @@ public String getContentName() { public int getTotalRound() { return room.getTotalRound(); } + + public boolean isRoomContentEnded(LocalDateTime now) { + return roundEndedAt.isBefore(now); + } } From 2733c2b01bc90d2b7608d19b37cd588bcd923b2c Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Fri, 2 Aug 2024 15:51:20 +0900 Subject: [PATCH 0465/1013] =?UTF-8?q?feat:=20=ED=98=84=EC=9E=AC=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B4=EB=93=9C=EA=B0=80=20=EB=81=9D=EB=82=AC?= =?UTF-8?q?=EB=8A=94=EC=A7=80=20=EC=97=AC=EB=B6=80=20=ED=99=95=EC=9D=B8?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/balanceContent.ts | 18 ++++++++++++ .../SelectContainer/SelectContainer.hook.ts | 28 +++++++++++++++++++ .../SelectContainer/SelectContainer.tsx | 18 +++++++++++- frontend/src/components/Timer/Timer.styled.ts | 3 -- frontend/src/constants/queryKeys.ts | 1 + 5 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 frontend/src/components/SelectContainer/SelectContainer.hook.ts diff --git a/frontend/src/apis/balanceContent.ts b/frontend/src/apis/balanceContent.ts index cf830f72..73eb3764 100644 --- a/frontend/src/apis/balanceContent.ts +++ b/frontend/src/apis/balanceContent.ts @@ -13,6 +13,10 @@ interface VoteParams extends ContentResultParams { optionId: number; } +interface RoundVoteIsFinished { + finished: boolean; +} + // 밸런스 게임 컨텐츠 가져오기 export const fetchBalanceContent = async (roomId = 1): Promise => { const res = await fetcher.get({ url: API_URL.balanceContent(roomId) }); @@ -78,3 +82,17 @@ export const fetchFinalGameResult = async (roomId = 1): Promise => { + const res = await fetcher.get({ + url: API_URL.roundVoteIsFinished(roomId, contentId), + }); + + const data = await res.json(); + + return data; +}; diff --git a/frontend/src/components/SelectContainer/SelectContainer.hook.ts b/frontend/src/components/SelectContainer/SelectContainer.hook.ts new file mode 100644 index 00000000..20219f24 --- /dev/null +++ b/frontend/src/components/SelectContainer/SelectContainer.hook.ts @@ -0,0 +1,28 @@ +import { useQuery } from '@tanstack/react-query'; + +import { fetchRoundVoteIsFinished } from '@/apis/balanceContent'; +import { QUERY_KEYS } from '@/constants/queryKeys'; + +const POLLING_DELAY = 1000; + +interface UseRoundIsFinishedQueryProps { + roomId: number; + contentId?: number; +} + +export const useRoundIsFinishedQuery = ({ roomId, contentId }: UseRoundIsFinishedQueryProps) => { + const roundIsFinishedQuery = useQuery({ + queryKey: [QUERY_KEYS.roundIsFinished, roomId, contentId], + queryFn: async () => { + if (typeof contentId === 'undefined') { + throw new Error('contentId 가 존재하지 않습니다.'); + } + return await fetchRoundVoteIsFinished({ roomId, contentId }); + }, + enabled: !!contentId, + refetchInterval: POLLING_DELAY, + refetchIntervalInBackground: true, + }); + + return { ...roundIsFinishedQuery, isFinished: roundIsFinishedQuery.data?.finished }; +}; diff --git a/frontend/src/components/SelectContainer/SelectContainer.tsx b/frontend/src/components/SelectContainer/SelectContainer.tsx index ba218fef..5417feed 100644 --- a/frontend/src/components/SelectContainer/SelectContainer.tsx +++ b/frontend/src/components/SelectContainer/SelectContainer.tsx @@ -1,19 +1,35 @@ -import { useState } from 'react'; +import { useEffect, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { useRoundIsFinishedQuery } from './SelectContainer.hook'; import { selectContainerLayout, selectSection } from './SelectContainer.styled'; import SelectButton from '../common/SelectButton/SelectButton'; import SelectOption from '@/components/SelectOption/SelectOption'; +import { ROUTES } from '@/constants/routes'; import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; const SelectContainer = () => { + const navigate = useNavigate(); + const { balanceContent, isLoading } = useBalanceContentQuery(); + const { isFinished } = useRoundIsFinishedQuery({ + roomId: 1, + contentId: balanceContent?.contentId, + }); + const [selectedId, setSelectedId] = useState(0); const handleSelectOption = (selectedId: number) => { setSelectedId(selectedId); }; + useEffect(() => { + if (isFinished) { + navigate(ROUTES.roundResult); + } + }, [isFinished, navigate]); + if (isLoading) return
      Loading...
      ; return ( diff --git a/frontend/src/components/Timer/Timer.styled.ts b/frontend/src/components/Timer/Timer.styled.ts index 6045b95e..40ac0b0d 100644 --- a/frontend/src/components/Timer/Timer.styled.ts +++ b/frontend/src/components/Timer/Timer.styled.ts @@ -24,9 +24,6 @@ const shake = keyframes` 60%{ transform: rotate(-10deg); } - 70%{ - transform: rotate(0deg); - } 100%{ transform: rotate(0deg); } diff --git a/frontend/src/constants/queryKeys.ts b/frontend/src/constants/queryKeys.ts index d51c1709..a9ea1b82 100644 --- a/frontend/src/constants/queryKeys.ts +++ b/frontend/src/constants/queryKeys.ts @@ -2,4 +2,5 @@ export const QUERY_KEYS = { balanceContent: 'balanceContent', gameResult: 'gameResult', roundVoteResult: 'roundVoteResult', + roundIsFinished: 'roundIsFinished', } as const; From 1bc50479584b3ea504f59c1cff36b456d24412ec Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sat, 3 Aug 2024 01:08:32 +0900 Subject: [PATCH 0466/1013] =?UTF-8?q?design:=20=ED=83=80=EC=9D=B4=EB=A8=B8?= =?UTF-8?q?=20=ED=81=AC=EA=B8=B0=20css=EB=A1=9C=20=EA=B4=80=EB=A6=AC=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/Timer/Timer.styled.ts | 2 ++ frontend/src/components/Timer/Timer.tsx | 8 +------- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/Timer/Timer.styled.ts b/frontend/src/components/Timer/Timer.styled.ts index 40ac0b0d..5e8dad7c 100644 --- a/frontend/src/components/Timer/Timer.styled.ts +++ b/frontend/src/components/Timer/Timer.styled.ts @@ -69,6 +69,8 @@ export const timerWrapper = (width: number) => css` export const timerIcon = css` position: absolute; + width: 4.8rem; + height: 4.8rem; `; export const timerIconShake = css` diff --git a/frontend/src/components/Timer/Timer.tsx b/frontend/src/components/Timer/Timer.tsx index b1e8d9ba..d2dcd7e3 100644 --- a/frontend/src/components/Timer/Timer.tsx +++ b/frontend/src/components/Timer/Timer.tsx @@ -18,13 +18,7 @@ const Timer = () => {
      - 타이머 + 타이머 {formatTimer(timerCount)}
      From d1d531ff9bbd0e463db713739d9c3f642be9e373 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sat, 3 Aug 2024 15:45:41 +0900 Subject: [PATCH 0467/1013] =?UTF-8?q?test:=20formatTimer=20=EC=9C=A0?= =?UTF-8?q?=ED=8B=B8=20=ED=95=A8=EC=88=98=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/Timer/Timer.hook.ts | 4 +--- frontend/src/components/Timer/Timer.test.tsx | 11 +++++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 frontend/src/components/Timer/Timer.test.tsx diff --git a/frontend/src/components/Timer/Timer.hook.ts b/frontend/src/components/Timer/Timer.hook.ts index e3393c75..321eb3d9 100644 --- a/frontend/src/components/Timer/Timer.hook.ts +++ b/frontend/src/components/Timer/Timer.hook.ts @@ -5,7 +5,7 @@ import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; const INITIAL_WIDTH = 100; const DELAY = 1000; -const useRoundTimer = () => { +export const useRoundTimer = () => { const { balanceContent } = useBalanceContentQuery(); const timeLimit = balanceContent?.timeLimit || 30; @@ -39,5 +39,3 @@ const useRoundTimer = () => { return { timerCount, barWidth, isAlmostFinished }; }; - -export { useRoundTimer }; diff --git a/frontend/src/components/Timer/Timer.test.tsx b/frontend/src/components/Timer/Timer.test.tsx new file mode 100644 index 00000000..ce7cdbca --- /dev/null +++ b/frontend/src/components/Timer/Timer.test.tsx @@ -0,0 +1,11 @@ +import { formatTimer } from './Timer.util'; + +describe('Timer 테스트', () => { + describe('formatTimer 유틸 함수 테스트', () => { + it('30초의 제한시간을 입력받으면 00:30 으로 포맷팅한 string값을 반환한다.', () => { + const formattedTimer = formatTimer(30); + + expect(formattedTimer).toBe('00:30'); + }); + }); +}); From ba6b510d218bead7269ad105d38e3cae681ecd11 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Sat, 3 Aug 2024 16:25:16 +0900 Subject: [PATCH 0468/1013] =?UTF-8?q?fix:=20=EB=8B=A4=EC=9D=8C=20=EB=9D=BC?= =?UTF-8?q?=EC=9A=B4=EB=93=9C=EB=A1=9C=20=EB=84=98=EC=96=B4=EA=B0=84?= =?UTF-8?q?=EB=8B=A4=EB=8A=94=20=EA=B2=83=EC=9D=84=20=EA=B0=95=EC=A1=B0?= =?UTF-8?q?=ED=95=98=EA=B8=B0=20=EC=9C=84=ED=95=B4=20path=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20#98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - /api/balances/rooms/{roomId}/next에서 /api/balances/rooms/{roomId}/next-round로 변경 --- .../ddangkong/controller/balance/room/RoomController.java | 2 +- .../ddangkong/controller/balance/room/RoomControllerTest.java | 4 ++-- .../documentation/balance/room/RoomDocumentationTest.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java index 12a4d3e3..83c6f182 100644 --- a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java +++ b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java @@ -44,7 +44,7 @@ public RoomJoinResponse joinRoom(@PathVariable @Positive Long roomId, @Valid @Re } @ResponseStatus(HttpStatus.NO_CONTENT) - @PatchMapping("/balances/rooms/{roomId}/next") + @PatchMapping("/balances/rooms/{roomId}/next-round") public void moveToNextRound(@PathVariable @Positive Long roomId) { roomService.moveToNextRound(roomId); } diff --git a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java index ecf0882d..7a746b29 100644 --- a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java @@ -124,7 +124,7 @@ class 다음_라운드_진행 { // when RestAssured.given().log().all() .pathParam("roomId", 1L) - .when().patch("/api/balances/rooms/{roomId}/next") + .when().patch("/api/balances/rooms/{roomId}/next-round") .then().log().all() .statusCode(204); } @@ -134,7 +134,7 @@ class 다음_라운드_진행 { // when & then RestAssured.given().log().all() .pathParam("roomId", -1L) - .when().patch("/api/balances/rooms/{roomId}/next") + .when().patch("/api/balances/rooms/{roomId}/next-round") .then().log().all() .statusCode(400); } diff --git a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java index 9be4b6c8..13a319f2 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java @@ -157,7 +157,7 @@ class 방_정보_조회 { @Nested class 다음_라운드로_이동 { - private static final String ENDPOINT = "/api/balances/rooms/{roomId}/next"; + private static final String ENDPOINT = "/api/balances/rooms/{roomId}/next-round"; @Test void 다음_라운드로_이동한다() throws Exception { From ef850f1091613f78f6cb4d4a6d5fa479c83e7a6d Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Sat, 3 Aug 2024 16:41:52 +0900 Subject: [PATCH 0469/1013] =?UTF-8?q?refactor:=20=EB=8D=94=20=EC=9D=B4?= =?UTF-8?q?=EC=83=81=20=EC=82=AC=EC=9A=A9=ED=95=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EB=8A=94=20RoomContent=EC=9D=98=20created=5Fat=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ddangkong/domain/balance/room/RoomContent.java | 3 +-- backend/src/test/resources/init-test.sql | 14 +++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java index cc08891b..2fc81bdc 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java @@ -1,6 +1,5 @@ package ddangkong.domain.balance.room; -import ddangkong.domain.BaseEntity; import ddangkong.domain.balance.content.BalanceContent; import ddangkong.domain.balance.content.Category; import ddangkong.exception.BadRequestException; @@ -20,7 +19,7 @@ @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter -public class RoomContent extends BaseEntity { +public class RoomContent { private static final int DELAY_MSEC = 2_000; // TODO SEC로 변경 diff --git a/backend/src/test/resources/init-test.sql b/backend/src/test/resources/init-test.sql index 94d4a8ce..08dcf858 100644 --- a/backend/src/test/resources/init-test.sql +++ b/backend/src/test/resources/init-test.sql @@ -18,13 +18,13 @@ VALUES ('EXAMPLE', '민초 vs 반민초'), ('EXAMPLE', '팔만대장경 다 읽기 vs 대장내시경 팔만번 하기'), ('EXAMPLE', '개구리 맛 초콜릿 vs 초콜릿 맛 개구리'); -INSERT INTO room_content (room_id, balance_content_id, round, created_at, round_ended_at, is_used) -VALUES (1, 2, 1, '2024-07-18 19:50:00.000', '2024-07-18 19:50:32.000', false), - (1, 1, 2, '2024-07-18 19:50:00.000', '2024-07-18 20:00:32.000', false), - (1, 3, 3, '2024-07-18 19:50:00.000', null, false), - (1, 4, 4, '2024-07-18 19:50:00.000', null, false), - (1, 5, 5, '2024-07-18 19:50:00.000', null, false), - (3, 1, 1, '2024-07-18 20:00:00.000', '2024-07-18 20:00:32.000', false); +INSERT INTO room_content (room_id, balance_content_id, round, round_ended_at, is_used) +VALUES (1, 2, 1, '2024-07-18 19:50:32.000', false), + (1, 1, 2, '2024-07-18 20:00:32.000', false), + (1, 3, 3, null, false), + (1, 4, 4, null, false), + (1, 5, 5, null, false), + (3, 1, 1, '2024-07-18 20:00:32.000', false); INSERT INTO balance_option (name, balance_content_id) VALUES ('민초', 1), From 73fcfce4afda485af43f7047556898840a0f412c Mon Sep 17 00:00:00 2001 From: jhon3242 Date: Sat, 3 Aug 2024 15:43:46 +0900 Subject: [PATCH 0470/1013] =?UTF-8?q?feat:=20Dockerfile=20=EB=B6=88?= =?UTF-8?q?=ED=95=84=EC=9A=94=ED=95=9C=20=EC=98=B5=EC=85=98=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20#96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ClockConfig를 통해 timezone을 설정했기 때문에 Dockerfile 지역 설정 옵션은 불필요해짐 #96 --- backend/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index c84213aa..495b9ddf 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -4,4 +4,4 @@ ARG JAR_FILE=build/libs/*.jar COPY ${JAR_FILE} app.jar -ENTRYPOINT [ "java", "-jar", "-Duser.timezone=Asia/Seoul", "-Dspring.profiles.active=dev", "app.jar" ] +ENTRYPOINT [ "java", "-jar", "-Dspring.profiles.active=dev", "app.jar" ] From 290fd6041f58e42bc013d7c91be76c6f621733e7 Mon Sep 17 00:00:00 2001 From: jhon3242 Date: Sat, 3 Aug 2024 15:59:58 +0900 Subject: [PATCH 0471/1013] =?UTF-8?q?fix:=20Dockerfile=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=EB=90=9C=20=EC=98=B5=EC=85=98=20=EB=8B=A4=EC=8B=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 해당 설정을 지우니 CI가 돌아가지 않는 문제가 발생하여 우선 다시 올림 #96 --- backend/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 495b9ddf..c84213aa 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -4,4 +4,4 @@ ARG JAR_FILE=build/libs/*.jar COPY ${JAR_FILE} app.jar -ENTRYPOINT [ "java", "-jar", "-Dspring.profiles.active=dev", "app.jar" ] +ENTRYPOINT [ "java", "-jar", "-Duser.timezone=Asia/Seoul", "-Dspring.profiles.active=dev", "app.jar" ] From b4672be2235e312d81303f92b4445d7947c3fa80 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sat, 3 Aug 2024 17:03:45 +0900 Subject: [PATCH 0472/1013] =?UTF-8?q?chore:=20jest=20clearMocks=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/jest.config.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/jest.config.json b/frontend/jest.config.json index 251d373a..f521e379 100644 --- a/frontend/jest.config.json +++ b/frontend/jest.config.json @@ -9,5 +9,6 @@ "test-utils": "/src/utils/test-utils" }, "setupFiles": ["./jest.polyfills.js"], - "setupFilesAfterEnv": ["/jest.setup.ts"] + "setupFilesAfterEnv": ["/jest.setup.ts"], + "clearMocks": true } From 3bc48eb71165509f4041087113cd567299e7963c Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sat, 3 Aug 2024 17:04:04 +0900 Subject: [PATCH 0473/1013] =?UTF-8?q?test:=20props=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EB=90=98=EB=8A=94=20=EC=A4=91=EB=B3=B5=20=EC=8A=A4?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=20=EC=A0=9C=EA=B1=B0=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/common/Button/Button.stories.tsx | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/frontend/src/components/common/Button/Button.stories.tsx b/frontend/src/components/common/Button/Button.stories.tsx index 9e83e395..e0b13e71 100644 --- a/frontend/src/components/common/Button/Button.stories.tsx +++ b/frontend/src/components/common/Button/Button.stories.tsx @@ -19,18 +19,10 @@ export default meta; type Story = StoryObj; -export const 클릭_가능한_버튼: Story = { +export const 기본_버튼: Story = { args: { - text: '확인', - }, - render: ({ ...args }) =>
    )} diff --git a/frontend/src/components/common/SelectButton/SelectButton.tsx b/frontend/src/components/common/SelectButton/SelectButton.tsx index f42628d0..7042ba16 100644 --- a/frontend/src/components/common/SelectButton/SelectButton.tsx +++ b/frontend/src/components/common/SelectButton/SelectButton.tsx @@ -5,13 +5,12 @@ import { bottomButtonLayout } from '../Button/Button.styled'; import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; interface SelectButtonProps { - isDisabled: boolean; selectedId: number; } -const SelectButton = ({ isDisabled, selectedId }: SelectButtonProps) => { +const SelectButton = ({ selectedId }: SelectButtonProps) => { const { balanceContent } = useBalanceContentQuery(); - const { mutate: selectComplete } = useSelectCompleteMutation({ + const { data, mutate: selectComplete } = useSelectCompleteMutation({ selectedId, contentId: balanceContent?.contentId, }); @@ -20,8 +19,8 @@ const SelectButton = ({ isDisabled, selectedId }: SelectButtonProps) => {
    From 557a683ad9deb5abf5da3ef078385259ad77ad95 Mon Sep 17 00:00:00 2001 From: useon Date: Sat, 3 Aug 2024 17:53:42 +0900 Subject: [PATCH 0483/1013] =?UTF-8?q?feat:=20=EC=8B=A4=EC=8B=9C=EA=B0=84?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=ED=98=84=EC=9E=AC=20=EB=9D=BC=EC=9A=B4?= =?UTF-8?q?=EB=93=9C=20=EC=A2=85=EB=A3=8C=20=EB=B0=8F=20=EA=B2=8C=EC=9E=84?= =?UTF-8?q?=20=EC=A2=85=EB=A3=8C=20=EC=97=AC=EB=B6=80=EB=A5=BC=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8=ED=95=98=EB=8A=94=20api=20=EA=B5=AC=ED=98=84=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/balanceContent.ts | 23 ++++++++++++++++++++++- frontend/src/constants/url.ts | 2 ++ frontend/src/types/balanceContent.ts | 5 +++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/frontend/src/apis/balanceContent.ts b/frontend/src/apis/balanceContent.ts index cf830f72..a534d507 100644 --- a/frontend/src/apis/balanceContent.ts +++ b/frontend/src/apis/balanceContent.ts @@ -1,7 +1,7 @@ import fetcher from './fetcher'; import { API_URL } from '@/constants/url'; -import { BalanceContent, GameFinalResult } from '@/types/balanceContent'; +import { BalanceContent, GameFinalResult, MyGameStatus } from '@/types/balanceContent'; import { RoundVoteResult } from '@/types/roundVoteResult'; interface ContentResultParams { @@ -13,6 +13,11 @@ interface VoteParams extends ContentResultParams { optionId: number; } +interface myGameStatusParams { + roomId: number; + currentRound: number; +} + // 밸런스 게임 컨텐츠 가져오기 export const fetchBalanceContent = async (roomId = 1): Promise => { const res = await fetcher.get({ url: API_URL.balanceContent(roomId) }); @@ -54,6 +59,22 @@ export const fetchRoundVoteResult = async ({ return data; }; +// 나의 라운드 종료 및 게임 종료 확인 +export const checkMyGameStatus = async ({ + roomId, + currentRound, +}: myGameStatusParams): Promise => { + const res = await fetcher.get({ + url: API_URL.myGameStatus(roomId, currentRound), + headers: { + 'Content-Type': `application/json`, + }, + }); + + const data = await res.json(); + return data; +}; + // 다음 라운드로 이동하기 export const moveNextRound = async (roomId = 1): Promise => { const res = await fetcher.post({ diff --git a/frontend/src/constants/url.ts b/frontend/src/constants/url.ts index ca92cbf3..b650db85 100644 --- a/frontend/src/constants/url.ts +++ b/frontend/src/constants/url.ts @@ -7,6 +7,8 @@ export const API_URL = { roundVoteResult: (roomId: number, contentId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/contents/${contentId}/vote-result`, moveNextRound: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/contents`, + myGameStatus: (roomId: number, round: number) => + `${BASE_URL}/api/balances/rooms/${roomId}?round=${round}`, finalResult: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/final`, }; diff --git a/frontend/src/types/balanceContent.ts b/frontend/src/types/balanceContent.ts index 71ea8ddf..de789e9b 100644 --- a/frontend/src/types/balanceContent.ts +++ b/frontend/src/types/balanceContent.ts @@ -14,6 +14,11 @@ export interface BalanceContent { }; } +export interface MyGameStatus { + isRoundFinished: boolean; + isGameFinished: boolean; +} + export interface GameFinalResult { rank: number; name: string; From 60aa23bca92c86a49c6eb1524c63a8d3f87b36b3 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sat, 3 Aug 2024 18:00:41 +0900 Subject: [PATCH 0484/1013] =?UTF-8?q?chore:=20=EC=8A=A4=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EC=A7=95=EB=90=9C=20=ED=8C=8C=EC=9D=BC=EB=A7=8C=20stylelint=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.husky/pre-commit | 2 +- frontend/package.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/frontend/.husky/pre-commit b/frontend/.husky/pre-commit index 5e9988bb..f450749a 100644 --- a/frontend/.husky/pre-commit +++ b/frontend/.husky/pre-commit @@ -1 +1 @@ -cd frontend && npx lint-staged && npm run lint:styled +cd frontend && npx lint-staged diff --git a/frontend/package.json b/frontend/package.json index e11f74c5..8597f6fb 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -91,7 +91,8 @@ "lint-staged": { "**/*.{ts,tsx}": [ "eslint --fix", - "prettier --write" + "prettier --write", + "stylelint ./src/**/*.styled.ts --fix" ] }, "msw": { From fce446d4ba5fddf55a825ede30ef4cc2f6769e05 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sat, 3 Aug 2024 18:02:14 +0900 Subject: [PATCH 0485/1013] =?UTF-8?q?refactor:=20SelectContainer=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=82=B4=EC=9D=98=20?= =?UTF-8?q?=EB=B9=84=EC=A6=88=EB=8B=88=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=ED=9B=85=EC=9C=BC=EB=A1=9C=20=EB=B6=84=EB=A6=AC=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SelectContainer/SelectContainer.hook.ts | 30 ++++++++- .../SelectContainer/SelectContainer.tsx | 64 ++++++------------- 2 files changed, 50 insertions(+), 44 deletions(-) diff --git a/frontend/src/components/SelectContainer/SelectContainer.hook.ts b/frontend/src/components/SelectContainer/SelectContainer.hook.ts index 1f7752c6..cd4023c0 100644 --- a/frontend/src/components/SelectContainer/SelectContainer.hook.ts +++ b/frontend/src/components/SelectContainer/SelectContainer.hook.ts @@ -1,8 +1,10 @@ import { useQuery } from '@tanstack/react-query'; -import { useParams } from 'react-router-dom'; +import { useEffect, useState } from 'react'; +import { useNavigate, useParams } from 'react-router-dom'; import { fetchRoundVoteIsFinished } from '@/apis/balanceContent'; import { QUERY_KEYS } from '@/constants/queryKeys'; +import { ROUTES } from '@/constants/routes'; const POLLING_DELAY = 1000; @@ -29,3 +31,29 @@ export const useRoundIsFinishedQuery = ({ contentId }: UseRoundIsFinishedQueryPr return { ...roundIsFinishedQuery, isFinished: roundIsFinishedQuery.data?.finished }; }; + +export const useRoundIsFinished = (contentId?: number) => { + const navigate = useNavigate(); + const { roomId } = useParams(); + const { isFinished } = useRoundIsFinishedQuery({ + contentId, + }); + + useEffect(() => { + if (isFinished) { + navigate(ROUTES.roundResult(Number(roomId)), { replace: true }); + } + }, [isFinished, navigate, roomId]); + + return { isFinished }; +}; + +export const useSelectOption = () => { + const [selectedId, setSelectedId] = useState(0); + + const handleSelectOption = (selectedId: number) => { + setSelectedId(selectedId); + }; + + return { selectedId, handleSelectOption }; +}; diff --git a/frontend/src/components/SelectContainer/SelectContainer.tsx b/frontend/src/components/SelectContainer/SelectContainer.tsx index fba664f1..02b31190 100644 --- a/frontend/src/components/SelectContainer/SelectContainer.tsx +++ b/frontend/src/components/SelectContainer/SelectContainer.tsx @@ -1,58 +1,36 @@ -import { useEffect, useState } from 'react'; -import { useNavigate, useParams } from 'react-router-dom'; - -import { useRoundIsFinishedQuery } from './SelectContainer.hook'; +import { useRoundIsFinished, useSelectOption } from './SelectContainer.hook'; import { selectContainerLayout, selectSection } from './SelectContainer.styled'; import SelectButton from '../common/SelectButton/SelectButton'; import SelectOption from '@/components/SelectOption/SelectOption'; -import { ROUTES } from '@/constants/routes'; import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; const SelectContainer = () => { - const navigate = useNavigate(); - const { roomId } = useParams(); - const { balanceContent, isLoading } = useBalanceContentQuery(); - const { isFinished } = useRoundIsFinishedQuery({ - contentId: balanceContent?.contentId, - }); - - const [selectedId, setSelectedId] = useState(0); - - const handleSelectOption = (selectedId: number) => { - setSelectedId(selectedId); - }; - - useEffect(() => { - if (isFinished) { - navigate(ROUTES.roundResult(Number(roomId)), { replace: true }); - } - }, [isFinished, navigate, roomId]); + const { selectedId, handleSelectOption } = useSelectOption(); + useRoundIsFinished(balanceContent?.contentId); if (isLoading) return
    Loading...
    ; + if (!balanceContent) return
    데이터가 없습니다.
    ; + return ( - <> - {balanceContent && ( -
    -
    - - VS - -
    - -
    - )} - +
    +
    + + VS + +
    + +
    ); }; From 7aa19b9dabf2c14f769d6761dd3d78bea8360eac Mon Sep 17 00:00:00 2001 From: useon Date: Sat, 3 Aug 2024 18:02:24 +0900 Subject: [PATCH 0486/1013] =?UTF-8?q?refactor:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=BB=A8=EB=B2=A4=EC=85=98=EC=97=90=20=EB=94=B0=EB=9D=BC=20css?= =?UTF-8?q?=20=EC=88=9C=EC=84=9C=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20border?= =?UTF-8?q?-radius=20theme=EC=97=90=20=EC=A0=95=EC=9D=98=EB=90=9C=20?= =?UTF-8?q?=ED=86=A0=ED=81=B0=EC=9C=BC=EB=A1=9C=20=EC=88=98=EC=A0=95=20#10?= =?UTF-8?q?6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/common/Modal/Modal.styled.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/common/Modal/Modal.styled.ts b/frontend/src/components/common/Modal/Modal.styled.ts index dc339698..d7c8c489 100644 --- a/frontend/src/components/common/Modal/Modal.styled.ts +++ b/frontend/src/components/common/Modal/Modal.styled.ts @@ -2,7 +2,7 @@ import { css } from '@emotion/react'; import { ModalProps } from './Modal'; -import { Theme } from '@/styles/Theme'; +import { borderRadius, Theme } from '@/styles/Theme'; export const modalBackdropLayout = css` display: flex; @@ -19,8 +19,8 @@ export const modalContentWrapper = ({ position }: Pick) position: fixed; left: 50%; flex-direction: column; - width: 24rem; gap: 1.6rem; + width: 24rem; height: fit-content; max-height: 70vh; min-height: 1.2rem; @@ -28,7 +28,7 @@ export const modalContentWrapper = ({ position }: Pick) margin: 0; padding: 2.4rem 3.2rem; border: none; - border-radius: 0.8rem; + border-radius: ${borderRadius.radius10}; background-color: white; box-sizing: border-box; @@ -113,14 +113,13 @@ export const modalTextButton = ({ height: ${buttonHeight}; padding: 1rem; border: none; + border-radius: 0.8rem; background-color: ${backgroundColor}; color: ${fontColor}; font-weight: bold; font-size: ${fontSize}; - border-radius: 0; - border-radius: 0.8rem; &:focus { outline: none; From baec679b655aef4e6f7a1dca86f61316a8c0d3e5 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Sat, 3 Aug 2024 18:10:40 +0900 Subject: [PATCH 0487/1013] =?UTF-8?q?feat:=20fixed=20clock=20extension=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#58?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/BaseControllerTest.java | 3 ++ .../ddangkong/service/BaseServiceTest.java | 3 ++ .../support/annotation/FixedClock.java | 18 +++++++ .../extension/FixedClockExtension.java | 54 +++++++++++++++++++ 4 files changed, 78 insertions(+) create mode 100644 backend/src/test/java/ddangkong/support/annotation/FixedClock.java create mode 100644 backend/src/test/java/ddangkong/support/extension/FixedClockExtension.java diff --git a/backend/src/test/java/ddangkong/controller/BaseControllerTest.java b/backend/src/test/java/ddangkong/controller/BaseControllerTest.java index 9568c379..5fe0f5e6 100644 --- a/backend/src/test/java/ddangkong/controller/BaseControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/BaseControllerTest.java @@ -5,14 +5,17 @@ import ddangkong.support.extension.DatabaseCleanerExtension; import io.restassured.RestAssured; +import java.time.Clock; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.test.context.jdbc.Sql; @ExtendWith(DatabaseCleanerExtension.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@SpyBean(Clock.class) @Sql(scripts = "/init-test.sql") public abstract class BaseControllerTest { diff --git a/backend/src/test/java/ddangkong/service/BaseServiceTest.java b/backend/src/test/java/ddangkong/service/BaseServiceTest.java index 3b52b23d..1582b2d0 100644 --- a/backend/src/test/java/ddangkong/service/BaseServiceTest.java +++ b/backend/src/test/java/ddangkong/service/BaseServiceTest.java @@ -3,12 +3,15 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import ddangkong.support.extension.DatabaseCleanerExtension; +import java.time.Clock; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.test.context.jdbc.Sql; @ExtendWith(DatabaseCleanerExtension.class) @SpringBootTest(webEnvironment = WebEnvironment.NONE) +@SpyBean(Clock.class) @Sql(scripts = "/init-test.sql") public abstract class BaseServiceTest { } diff --git a/backend/src/test/java/ddangkong/support/annotation/FixedClock.java b/backend/src/test/java/ddangkong/support/annotation/FixedClock.java new file mode 100644 index 00000000..64182a70 --- /dev/null +++ b/backend/src/test/java/ddangkong/support/annotation/FixedClock.java @@ -0,0 +1,18 @@ +package ddangkong.support.annotation; + +import ddangkong.support.extension.FixedClockExtension; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.junit.jupiter.api.extension.ExtendWith; + +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@ExtendWith(FixedClockExtension.class) +public @interface FixedClock { + + String date(); + + String time(); +} diff --git a/backend/src/test/java/ddangkong/support/extension/FixedClockExtension.java b/backend/src/test/java/ddangkong/support/extension/FixedClockExtension.java new file mode 100644 index 00000000..3dbfb129 --- /dev/null +++ b/backend/src/test/java/ddangkong/support/extension/FixedClockExtension.java @@ -0,0 +1,54 @@ +package ddangkong.support.extension; + + +import static org.mockito.Mockito.when; + +import ddangkong.support.annotation.FixedClock; +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneOffset; +import java.util.regex.Pattern; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +public class FixedClockExtension implements BeforeEachCallback { + + private static final Pattern DATE_PATTERN = Pattern.compile("\\d{4}-\\d{2}-\\d{2}"); + private static final Pattern TIME_PATTERN = Pattern.compile("\\d{2}:\\d{2}:\\d{2}"); + + @Override + public void beforeEach(ExtensionContext context) { + Clock clock = SpringExtension.getApplicationContext(context).getBean(Clock.class); + FixedClock fixedClockAnnotation = getFixedClockAnnotation(context); + + String date = getDate(fixedClockAnnotation); + String time = getTime(fixedClockAnnotation); + when(clock.instant()).thenReturn(Instant.parse("%sT%sZ".formatted(date, time))); + when(clock.getZone()).thenReturn(ZoneOffset.UTC); + } + + private FixedClock getFixedClockAnnotation(ExtensionContext context) { + FixedClock fixedClockAnnotation = context.getRequiredTestMethod().getDeclaredAnnotation(FixedClock.class); + if (fixedClockAnnotation == null) { + fixedClockAnnotation = context.getRequiredTestClass().getDeclaredAnnotation(FixedClock.class); + } + return fixedClockAnnotation; + } + + private String getDate(FixedClock fixedClockAnnotation) { + String date = fixedClockAnnotation.date(); + if (!DATE_PATTERN.matcher(date).matches()) { + throw new IllegalArgumentException("yyyy-MM-dd의 date 포맷이어야 합니다. invalid date: %s".formatted(date)); + } + return date; + } + + private String getTime(FixedClock fixedClockAnnotation) { + String time = fixedClockAnnotation.time(); + if (!TIME_PATTERN.matcher(time).matches()) { + throw new IllegalArgumentException("HH:mm:ss의 time 포맷이어야 합니다. invalid time: %s".formatted(time)); + } + return time; + } +} From 62b2700210b8f4ae98e69b5565f613ad3fe725c2 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Sat, 3 Aug 2024 18:26:02 +0900 Subject: [PATCH 0488/1013] =?UTF-8?q?refactor:=20test=20clock=20config=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0=20=EB=B0=8F=20fixed=20clock=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=20#58?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vote/BalanceVoteControllerTest.java | 5 ++-- .../balance/vote/BalanceVoteServiceTest.java | 5 ++-- .../support/config/TestClockConfig.java | 26 ------------------- 3 files changed, 4 insertions(+), 32 deletions(-) delete mode 100644 backend/src/test/java/ddangkong/support/config/TestClockConfig.java diff --git a/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java index 5a69fbdc..394f8f50 100644 --- a/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java @@ -5,17 +5,16 @@ import ddangkong.controller.BaseControllerTest; import ddangkong.controller.balance.vote.dto.BalanceVoteRequest; import ddangkong.controller.balance.vote.dto.BalanceVoteResponse; -import ddangkong.support.config.TestClockConfig; +import ddangkong.support.annotation.FixedClock; import io.restassured.RestAssured; import io.restassured.http.ContentType; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.springframework.context.annotation.Import; -@Import(TestClockConfig.class) class BalanceVoteControllerTest extends BaseControllerTest { @Nested + @FixedClock(date = "2024-07-18", time = "20:00:02") class 투표_생성 { private static final Long ROOM_ID = 1L; diff --git a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java index 06c60e96..5b83e856 100644 --- a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java @@ -12,20 +12,19 @@ import ddangkong.controller.balance.vote.dto.BalanceVoteResultResponse; import ddangkong.exception.BadRequestException; import ddangkong.service.BaseServiceTest; -import ddangkong.support.config.TestClockConfig; +import ddangkong.support.annotation.FixedClock; import java.util.List; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Import; -@Import(TestClockConfig.class) class BalanceVoteServiceTest extends BaseServiceTest { @Autowired private BalanceVoteService balanceVoteService; @Nested + @FixedClock(date = "2024-07-18", time = "20:00:02") class 투표_생성 { @Test diff --git a/backend/src/test/java/ddangkong/support/config/TestClockConfig.java b/backend/src/test/java/ddangkong/support/config/TestClockConfig.java deleted file mode 100644 index ec1cb1dd..00000000 --- a/backend/src/test/java/ddangkong/support/config/TestClockConfig.java +++ /dev/null @@ -1,26 +0,0 @@ -package ddangkong.support.config; - -import java.time.Clock; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Primary; - -@TestConfiguration -public class TestClockConfig { - - @Primary - @Bean - public Clock testClock() { - String dateTimeString = "2024-07-18 20:00:02.000"; - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); - LocalDateTime customDateTime = LocalDateTime.parse(dateTimeString, formatter); - ZonedDateTime customZonedDateTime = customDateTime.atZone(ZoneId.of("Asia/Seoul")); - Instant customInstant = customZonedDateTime.toInstant(); - return Clock.fixed(customInstant, ZoneId.of("Asia/Seoul")); - } -} From 654540dc1bdc2dc89cb4f1dd71d5a7ad01923e7a Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Sat, 3 Aug 2024 20:13:56 +0900 Subject: [PATCH 0489/1013] =?UTF-8?q?feat:=20RoomContent=20=EC=BB=A8?= =?UTF-8?q?=ED=85=90=EC=B8=A0=20=EC=82=AC=EC=9A=A9=20=EC=97=AC=EB=B6=80,?= =?UTF-8?q?=20=EB=9D=BC=EC=9A=B4=EB=93=9C=20=EC=9D=BC=EC=B9=98=20=EC=97=AC?= =?UTF-8?q?=EB=B6=80=20=EA=B2=80=EC=A6=9D=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20#58?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/balance/room/RoomContent.java | 25 ++++++ .../domain/balance/room/RoomContentTest.java | 76 +++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java index 78f3d712..98dd3736 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java @@ -43,6 +43,18 @@ public class RoomContent extends BaseEntity { @Column(nullable = false) private boolean isUsed; + public RoomContent(Room room, + BalanceContent balanceContent, + int round, + LocalDateTime roundEndedAt, + boolean isUsed) { + this.room = room; + this.balanceContent = balanceContent; + this.round = round; + this.roundEndedAt = roundEndedAt; + this.isUsed = isUsed; + } + public boolean isRoundOver(LocalDateTime currentTime) { return currentTime.isAfter(getRoundEndedAt()); } @@ -73,4 +85,17 @@ public LocalDateTime getRoundEndedAt() { } return roundEndedAt; } + + public void validateAlreadyUsed() { + if (isUsed) { + throw new BadRequestException("이미 사용된 컨텐츠입니다."); + } + } + + public void validateSameRound(int round) { + if (this.round != round) { + throw new BadRequestException("컨텐츠의 라운드가 일치하지 않습니다. 방 컨텐츠의 라운드 : %d, 요청한 라운드 : %d" + .formatted(this.round, round)); + } + } } diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java new file mode 100644 index 00000000..b224bd03 --- /dev/null +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java @@ -0,0 +1,76 @@ +package ddangkong.domain.balance.room; + +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import ddangkong.domain.balance.content.BalanceContent; +import ddangkong.domain.balance.content.Category; +import ddangkong.exception.BadRequestException; +import java.time.LocalDateTime; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +class RoomContentTest { + + private static final Room ROOM = Room.createNewRoom(); + private static final BalanceContent BALANCE_CONTENT = new BalanceContent(Category.EXAMPLE, "치킨 vs 피자"); + + @Nested + class 컨텐츠_사용_여부 { + + private static final int ROUND = 1; + private static final LocalDateTime ROUND_ENDED_AT = LocalDateTime.parse("2024-08-03T20:00:02"); + + @Test + void 사용된_컨텐츠면_예외가_발생한다() { + // given + boolean isUsed = true; + RoomContent roomContent = new RoomContent(ROOM, BALANCE_CONTENT, ROUND, ROUND_ENDED_AT, isUsed); + + // when & then + assertThatThrownBy(roomContent::validateAlreadyUsed) + .isExactlyInstanceOf(BadRequestException.class) + .hasMessageContaining("이미 사용된 컨텐츠입니다."); + } + + @Test + void 사용된_컨텐츠가_아니면_예외가_발생하지_않는다() { + // given + boolean isUsed = false; + RoomContent roomContent = new RoomContent(ROOM, BALANCE_CONTENT, ROUND, ROUND_ENDED_AT, isUsed); + + // when & then + assertThatCode(roomContent::validateAlreadyUsed).doesNotThrowAnyException(); + } + } + + @Nested + class 라운드_일치_여부 { + + private static final LocalDateTime ROUND_ENDED_AT = LocalDateTime.parse("2024-08-03T20:00:02"); + private static final boolean IS_USED = false; + + @Test + void 라운드가_일치하지_않으면_예외가_발생한다() { + // given + int round = 2; + RoomContent roomContent = new RoomContent(ROOM, BALANCE_CONTENT, round, ROUND_ENDED_AT, IS_USED); + int invalidRound = 1; + + // when & then + assertThatThrownBy(() -> roomContent.validateSameRound(invalidRound)) + .isExactlyInstanceOf(BadRequestException.class) + .hasMessageContaining("라운드가 일치하지 않습니다."); + } + + @Test + void 라운드가_일치하면_예외가_발생하지_않는다() { + // given + int round = 1; + RoomContent roomContent = new RoomContent(ROOM, BALANCE_CONTENT, round, ROUND_ENDED_AT, IS_USED); + + // when & then + assertThatCode(() -> roomContent.validateSameRound(round)).doesNotThrowAnyException(); + } + } +} From 017f7d575f5d2d84d2f5a453c596b738a98b6ef6 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Sat, 3 Aug 2024 20:55:16 +0900 Subject: [PATCH 0490/1013] =?UTF-8?q?refactor:=20Clock=20=EA=B0=9D?= =?UTF-8?q?=EC=B2=B4=EB=A5=BC=20=EC=9D=B4=EC=9A=A9=ED=95=98=EC=97=AC=20?= =?UTF-8?q?=ED=98=84=EC=9E=AC=20=EC=8B=9C=EA=B0=81=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?#98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ddangkong/service/balance/room/RoomService.java | 5 ++++- .../java/ddangkong/service/balance/room/RoomServiceTest.java | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index 7e6d8893..1ff51ca6 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -12,6 +12,7 @@ import ddangkong.domain.member.MemberRepository; import ddangkong.exception.InternalServerException; import ddangkong.service.balance.room.dto.RoundFinishedResponse; +import java.time.Clock; import java.time.LocalDateTime; import java.util.List; import lombok.RequiredArgsConstructor; @@ -28,6 +29,8 @@ public class RoomService { private final RoomContentRepository roomContentRepository; + private final Clock clock; + @Transactional(readOnly = true) public RoomInfoResponse findRoomInfo(Long roomId) { Room room = roomRepository.getById(roomId); @@ -66,7 +69,7 @@ public void moveToNextRound(Long roomId) { if (room.isGameProgress()) { RoomContent roomContent = getCurrentRoomContent(room); - roomContent.startRound(LocalDateTime.now()); // TODO #105와 merge될 때 수정 예정 + roomContent.startRound(LocalDateTime.now(clock)); } } diff --git a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java index d1edf3b5..eebe0e75 100644 --- a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java @@ -18,13 +18,16 @@ import ddangkong.exception.BadRequestException; import ddangkong.service.BaseServiceTest; import ddangkong.service.balance.room.dto.RoundFinishedResponse; +import ddangkong.support.config.TestClockConfig; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Import; +@Import(TestClockConfig.class) class RoomServiceTest extends BaseServiceTest { @Autowired From 90394984ae4d17dcafea52053b3c4d4f670855dc Mon Sep 17 00:00:00 2001 From: useon Date: Sat, 3 Aug 2024 21:06:28 +0900 Subject: [PATCH 0491/1013] =?UTF-8?q?feat:=20=EB=9D=BC=EC=9A=B4=EB=93=9C?= =?UTF-8?q?=20=EC=A2=85=EB=A3=8C=20=EC=97=AC=EB=B6=80=20=EB=B0=8F=20?= =?UTF-8?q?=EA=B2=8C=EC=9E=84=20=EC=A2=85=EB=A3=8C=20=EC=97=AC=EB=B6=80=20?= =?UTF-8?q?=ED=99=95=EC=9D=B8=20=EC=BB=A4=EC=8A=A4=ED=85=80=20=ED=9B=85=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/constants/queryKeys.ts | 1 + frontend/src/hooks/useMyGameStatusQuery.ts | 37 ++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 frontend/src/hooks/useMyGameStatusQuery.ts diff --git a/frontend/src/constants/queryKeys.ts b/frontend/src/constants/queryKeys.ts index d51c1709..cd343e4f 100644 --- a/frontend/src/constants/queryKeys.ts +++ b/frontend/src/constants/queryKeys.ts @@ -2,4 +2,5 @@ export const QUERY_KEYS = { balanceContent: 'balanceContent', gameResult: 'gameResult', roundVoteResult: 'roundVoteResult', + myGameStatus: 'myGameStatus', } as const; diff --git a/frontend/src/hooks/useMyGameStatusQuery.ts b/frontend/src/hooks/useMyGameStatusQuery.ts new file mode 100644 index 00000000..9e27e2e8 --- /dev/null +++ b/frontend/src/hooks/useMyGameStatusQuery.ts @@ -0,0 +1,37 @@ +import { useQuery } from '@tanstack/react-query'; + +import { checkMyGameStatus } from '@/apis/balanceContent'; +import { QUERY_KEYS } from '@/constants/queryKeys'; +import { BalanceContent } from '@/types/balanceContent'; + +interface useMyGameStatusQueryProps { + balanceContent: BalanceContent | undefined; + roomId: number; +} + +const useMyGameStatusQuery = ({ roomId, balanceContent }: useMyGameStatusQueryProps) => { + const myGameStatusQuery = useQuery({ + queryKey: [QUERY_KEYS.myGameStatus, balanceContent, roomId, balanceContent?.currentRound], + queryFn: () => { + if (!balanceContent) { + throw new Error('balanceContent 가 존재하지 않습니다.'); + } + return checkMyGameStatus({ + roomId: roomId, + currentRound: balanceContent.currentRound, + }); + }, + enabled: !!balanceContent, + staleTime: 0, + refetchInterval: 1000, + refetchOnWindowFocus: true, + }); + + return { + ...myGameStatusQuery, + isRoundFinished: myGameStatusQuery.data?.isRoundFinished, + isGameFinished: myGameStatusQuery.data?.isGameFinished, + }; +}; + +export default useMyGameStatusQuery; From 5caa4ed07c7e57e13d09237b9e611784e083308c Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sat, 3 Aug 2024 21:06:55 +0900 Subject: [PATCH 0492/1013] =?UTF-8?q?refactor:=20roomId=EB=A5=BC=20?= =?UTF-8?q?=EC=99=B8=EB=B6=80=EC=97=90=EC=84=9C=20=EC=A3=BC=EC=9E=85?= =?UTF-8?q?=EB=B0=9B=EB=8A=94=20=EA=B5=AC=EC=A1=B0=EB=A1=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OptionParticipantsContainer.tsx | 5 +++++ .../components/TabContentContainer/TabContentContainer.tsx | 5 ++++- frontend/src/hooks/useRoundVoteResultQuery.ts | 7 +++---- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx index 53ae2499..f419440a 100644 --- a/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx +++ b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx @@ -1,3 +1,5 @@ +import { useParams } from 'react-router-dom'; + import { dividerLine, optionParticipantsContainerLayout, @@ -9,8 +11,11 @@ import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; import useRoundVoteResultQuery from '@/hooks/useRoundVoteResultQuery'; const OptionParticipantsContainer = () => { + const { roomId } = useParams(); + const { balanceContent } = useBalanceContentQuery(); const { groupRoundResult } = useRoundVoteResultQuery({ + roomId: Number(roomId), contentId: balanceContent?.contentId, }); diff --git a/frontend/src/components/TabContentContainer/TabContentContainer.tsx b/frontend/src/components/TabContentContainer/TabContentContainer.tsx index 8c7d0510..ee6bd9f3 100644 --- a/frontend/src/components/TabContentContainer/TabContentContainer.tsx +++ b/frontend/src/components/TabContentContainer/TabContentContainer.tsx @@ -1,4 +1,4 @@ -import { useNavigate } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router-dom'; import { alertText, @@ -27,9 +27,12 @@ interface TabContentContainerProps { } const TabContentContainer = ({ isGroupTabActive }: TabContentContainerProps) => { + const { roomId } = useParams(); const navigate = useNavigate(); + const { balanceContent } = useBalanceContentQuery(); const { groupRoundResult, totalResult } = useRoundVoteResultQuery({ + roomId: Number(roomId), contentId: balanceContent?.contentId, }); diff --git a/frontend/src/hooks/useRoundVoteResultQuery.ts b/frontend/src/hooks/useRoundVoteResultQuery.ts index 5b9bb54a..09d9cb4e 100644 --- a/frontend/src/hooks/useRoundVoteResultQuery.ts +++ b/frontend/src/hooks/useRoundVoteResultQuery.ts @@ -1,5 +1,4 @@ import { useQuery, UseQueryResult } from '@tanstack/react-query'; -import { useParams } from 'react-router-dom'; import INITIAL_VALUE from '../mocks/data/roundVoteResultInitialValue.json'; @@ -8,6 +7,7 @@ import { QUERY_KEYS } from '@/constants/queryKeys'; import { Group, RoundVoteResult, Total } from '@/types/roundVoteResult'; interface UseRoundVoteResultQueryProps { + roomId: number; contentId?: number; } @@ -17,10 +17,9 @@ type RoundVoteResultQueryResponse = UseQueryResult & { }; const useRoundVoteResultQuery = ({ + roomId, contentId, }: UseRoundVoteResultQueryProps): RoundVoteResultQueryResponse => { - const { roomId } = useParams(); - const roundVoteResultQuery = useQuery({ queryKey: [QUERY_KEYS.roundVoteResult, roomId, contentId], queryFn: async () => { @@ -32,7 +31,7 @@ const useRoundVoteResultQuery = ({ throw new Error('방이 존재하지 않습니다.'); } - return await fetchRoundVoteResult({ roomId: Number(roomId), contentId }); + return await fetchRoundVoteResult({ roomId, contentId }); }, placeholderData: INITIAL_VALUE, enabled: !!contentId, From e5d7ee82b2b80b214a2891dd00b26119e7d32111 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sat, 3 Aug 2024 21:07:20 +0900 Subject: [PATCH 0493/1013] =?UTF-8?q?test:=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EC=97=AD=ED=95=A0=20=EB=B6=84=EB=A6=AC=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B8=ED=95=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=88=98=EC=A0=95=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RoundVoteContainer.test.tsx | 11 ------- .../TabContentContainer.test.tsx | 31 +++++++++++++++++++ 2 files changed, 31 insertions(+), 11 deletions(-) create mode 100644 frontend/src/components/TabContentContainer/TabContentContainer.test.tsx diff --git a/frontend/src/components/RoundVoteContainer/RoundVoteContainer.test.tsx b/frontend/src/components/RoundVoteContainer/RoundVoteContainer.test.tsx index 24d953b7..e787f0a0 100644 --- a/frontend/src/components/RoundVoteContainer/RoundVoteContainer.test.tsx +++ b/frontend/src/components/RoundVoteContainer/RoundVoteContainer.test.tsx @@ -5,17 +5,6 @@ import { customRender } from 'test-utils'; import RoundVoteContainer from './RoundVoteContainer'; describe('RoundVoteContainer 컴포넌트 테스트', () => { - it('라운드 결과 그룹원들이 선택한 퍼센트를 카운팅 애니메이션으로 보여준다.', async () => { - customRender(); - - await waitFor( - () => { - expect(screen.getByText('73%')).toBeInTheDocument(); - expect(screen.getByText('27%')).toBeInTheDocument(); - }, - { timeout: 3000 }, - ); - }); it('기본 탭인 그룹 탭에서, 전체 탭을 클릭하면 전체 사용자 통계를 퍼센트로 보여준다.', async () => { const user = userEvent.setup(); customRender(); diff --git a/frontend/src/components/TabContentContainer/TabContentContainer.test.tsx b/frontend/src/components/TabContentContainer/TabContentContainer.test.tsx new file mode 100644 index 00000000..afa0eb6d --- /dev/null +++ b/frontend/src/components/TabContentContainer/TabContentContainer.test.tsx @@ -0,0 +1,31 @@ +import { renderHook, screen, waitFor } from '@testing-library/react'; +import { customRender, wrapper } from 'test-utils'; + +import TabContentContainer from './TabContentContainer'; + +import useRoundVoteResultQuery from '@/hooks/useRoundVoteResultQuery'; + +describe('TabContentContainer 컴포넌트 테스트', () => { + it('라운드 결과 그룹원들이 선택한 퍼센트를 카운팅 애니메이션으로 보여준다.', async () => { + customRender(); + + await waitFor( + () => { + expect(screen.getByText('73%')).toBeInTheDocument(); + expect(screen.getByText('27%')).toBeInTheDocument(); + }, + { timeout: 3000 }, + ); + }); + + it('useRoundVoteResultQuery 커스텀 훅이 선택지에 대한 비율을 반환한다.', async () => { + const { result } = renderHook(() => useRoundVoteResultQuery({ roomId: 1, contentId: 1 }), { + wrapper, + }); + + await waitFor(() => { + expect(result.current.data?.group.firstOption.percent).toBe(73); + expect(result.current.data?.group.secondOption.percent).toBe(27); + }); + }); +}); From 8e759cd0326a1098ffe77241337cf0c59c875b90 Mon Sep 17 00:00:00 2001 From: useon Date: Sat, 3 Aug 2024 21:24:10 +0900 Subject: [PATCH 0494/1013] =?UTF-8?q?feat:=20OptionParticipantsContainer?= =?UTF-8?q?=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=82=B4=20=EB=B9=84?= =?UTF-8?q?=EC=A6=88=EB=8B=88=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20=EC=BB=A4?= =?UTF-8?q?=EC=8A=A4=ED=85=80=20=ED=9B=85=20=EA=B5=AC=ED=98=84=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OptionParticipantsContainer.hook.ts | 25 +++++++++++++++++++ .../OptionParticipantsContainer.tsx | 12 +++------ 2 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.hook.ts diff --git a/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.hook.ts b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.hook.ts new file mode 100644 index 00000000..818ff32d --- /dev/null +++ b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.hook.ts @@ -0,0 +1,25 @@ +import { useLocation } from 'react-router-dom'; + +import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; +import useMyGameStatusQuery from '@/hooks/useMyGameStatusQuery'; +import useRoundVoteResultQuery from '@/hooks/useRoundVoteResultQuery'; + +const useOptionParticipants = () => { + const { search } = useLocation(); + const roomId = Number(new URLSearchParams(search).get('roomId')); + + const { balanceContent } = useBalanceContentQuery(); + + const { groupRoundResult } = useRoundVoteResultQuery({ + contentId: balanceContent?.contentId, + roomId: roomId, + }); + + const { isRoundFinished, isGameFinished } = useMyGameStatusQuery({ balanceContent, roomId }); + + return { + groupRoundResult, + }; +}; + +export default useOptionParticipants; diff --git a/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx index 2e6eddeb..06402451 100644 --- a/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx +++ b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx @@ -1,3 +1,4 @@ +import useOptionParticipantsQuery from './OptionParticipantsContainer.hook'; import { dividerLine, optionParticipantsContainerLayout, @@ -5,17 +6,10 @@ import { import OptionParticipants from '../OptionParticipants/OptionParticipants'; import TopicContainer from '../TopicContainer/TopicContainer'; -import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; -import useRoundVoteResultQuery from '@/hooks/useRoundVoteResultQuery'; - const OptionParticipantsContainer = () => { - const { balanceContent } = useBalanceContentQuery(); - const { groupRoundResult } = useRoundVoteResultQuery({ - contentId: balanceContent?.contentId, - roomId: 1, - }); + const { groupRoundResult } = useOptionParticipantsQuery(); - if (!balanceContent || !groupRoundResult) { + if (!groupRoundResult) { return null; } From 5b8313c1758ea516e0a7244f5c1c0b4a098b96f8 Mon Sep 17 00:00:00 2001 From: useon Date: Sat, 3 Aug 2024 21:27:59 +0900 Subject: [PATCH 0495/1013] =?UTF-8?q?feat:=20=ED=88=AC=ED=91=9C=20?= =?UTF-8?q?=ED=98=84=ED=99=A9=20=ED=8E=98=EC=9D=B4=EC=A7=80=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EA=B2=8C=EC=9E=84=20=EC=A7=84=ED=96=89=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=EC=97=90=20=EB=94=B0=EB=9D=BC=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EB=9D=BC=EC=9A=B0=ED=8C=85=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OptionParticipantsContainer.hook.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.hook.ts b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.hook.ts index 818ff32d..ef72d693 100644 --- a/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.hook.ts +++ b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.hook.ts @@ -1,5 +1,7 @@ -import { useLocation } from 'react-router-dom'; +import { useEffect } from 'react'; +import { useLocation, useNavigate } from 'react-router-dom'; +import { ROUTES } from '@/constants/routes'; import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; import useMyGameStatusQuery from '@/hooks/useMyGameStatusQuery'; import useRoundVoteResultQuery from '@/hooks/useRoundVoteResultQuery'; @@ -7,6 +9,7 @@ import useRoundVoteResultQuery from '@/hooks/useRoundVoteResultQuery'; const useOptionParticipants = () => { const { search } = useLocation(); const roomId = Number(new URLSearchParams(search).get('roomId')); + const navigate = useNavigate(); const { balanceContent } = useBalanceContentQuery(); @@ -17,6 +20,15 @@ const useOptionParticipants = () => { const { isRoundFinished, isGameFinished } = useMyGameStatusQuery({ balanceContent, roomId }); + useEffect(() => { + if (isGameFinished) { + navigate(ROUTES.gameResult); + } + if (isRoundFinished) { + navigate(ROUTES.game); + } + }, [isRoundFinished, isGameFinished]); + return { groupRoundResult, }; From 934b323ac115fd578d244d51e533bba4da71447a Mon Sep 17 00:00:00 2001 From: useon Date: Sat, 3 Aug 2024 21:44:55 +0900 Subject: [PATCH 0496/1013] =?UTF-8?q?refactor:=20useEffect=EC=97=90?= =?UTF-8?q?=EC=84=9C=20navigate=20=ED=95=A8=EC=88=98=20=EB=B6=84=EB=A6=AC?= =?UTF-8?q?=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OptionParticipantsContainer.hook.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.hook.ts b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.hook.ts index ef72d693..c2d88a10 100644 --- a/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.hook.ts +++ b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.hook.ts @@ -20,12 +20,20 @@ const useOptionParticipants = () => { const { isRoundFinished, isGameFinished } = useMyGameStatusQuery({ balanceContent, roomId }); + const goToGameResult = () => { + navigate(ROUTES.gameResult); + }; + + const goToNextRound = async () => { + navigate(ROUTES.game); + }; + useEffect(() => { if (isGameFinished) { - navigate(ROUTES.gameResult); + goToGameResult(); } if (isRoundFinished) { - navigate(ROUTES.game); + goToNextRound(); } }, [isRoundFinished, isGameFinished]); From b605ecbe44eafe6cb2d56af659fc55d2b824620b Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Sat, 3 Aug 2024 21:56:02 +0900 Subject: [PATCH 0497/1013] =?UTF-8?q?feat:=20=EB=AA=A8=EB=93=A0=20?= =?UTF-8?q?=ED=88=AC=ED=91=9C=EA=B0=80=20=EB=81=9D=EB=82=AC=EB=8A=94?= =?UTF-8?q?=EC=A7=80=20=ED=99=95=EC=9D=B8=ED=95=98=EB=8A=94=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80=20#58?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/balance/option/BalanceOption.java | 5 + .../balance/room/RoomContentRepository.java | 9 ++ .../balance/vote/BalanceVoteService.java | 25 +++ .../vote/dto/VoteFinishedResponse.java | 14 ++ .../ddangkong/service/BaseServiceTest.java | 25 +++ .../balance/vote/BalanceVoteServiceTest.java | 145 ++++++++++++++++++ .../support/fixture/MemberFixture.java | 23 +++ 7 files changed, 246 insertions(+) create mode 100644 backend/src/main/java/ddangkong/service/balance/vote/dto/VoteFinishedResponse.java create mode 100644 backend/src/test/java/ddangkong/support/fixture/MemberFixture.java diff --git a/backend/src/main/java/ddangkong/domain/balance/option/BalanceOption.java b/backend/src/main/java/ddangkong/domain/balance/option/BalanceOption.java index bc65918d..1be54e6d 100644 --- a/backend/src/main/java/ddangkong/domain/balance/option/BalanceOption.java +++ b/backend/src/main/java/ddangkong/domain/balance/option/BalanceOption.java @@ -28,4 +28,9 @@ public class BalanceOption { @ManyToOne(optional = false, fetch = FetchType.LAZY) @JoinColumn(name = "balance_content_id", nullable = false) private BalanceContent balanceContent; + + public BalanceOption(String name, BalanceContent balanceContent) { + this.name = name; + this.balanceContent = balanceContent; + } } diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomContentRepository.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomContentRepository.java index dd0b3f38..6640da51 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomContentRepository.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomContentRepository.java @@ -1,9 +1,18 @@ package ddangkong.domain.balance.room; +import ddangkong.domain.balance.content.BalanceContent; +import ddangkong.exception.BadRequestException; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; public interface RoomContentRepository extends JpaRepository { Optional findByRoomAndRound(Room room, int round); + + Optional findByRoomAndBalanceContent(Room room, BalanceContent balanceContent); + + default RoomContent getByRoomAndBalanceContent(Room room, BalanceContent balanceContent) { + return findByRoomAndBalanceContent(room, balanceContent) + .orElseThrow(() -> new BadRequestException("방에 존재하지 않은 컨텐츠입니다.")); + } } diff --git a/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java b/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java index dbef7bb6..1c5e3a47 100644 --- a/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java +++ b/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java @@ -19,6 +19,7 @@ import ddangkong.domain.member.Member; import ddangkong.domain.member.MemberRepository; import ddangkong.exception.BadRequestException; +import ddangkong.service.balance.vote.dto.VoteFinishedResponse; import java.time.Clock; import java.time.LocalDateTime; import java.util.List; @@ -120,4 +121,28 @@ private void validateBalanceContent(Long balanceContentId, BalanceContent balanc throw new BadRequestException("현재 진행중인 질문의 컨텐츠와 일치하지 않는 요청입니다."); } } + + @Transactional(readOnly = true) + public VoteFinishedResponse getAllVoteFinished(Long roomId, Long contentId) { + Room room = roomRepository.getById(roomId); + BalanceContent balanceContent = balanceContentRepository.getById(contentId); + if (isRoundFinished(room, balanceContent)) { + return VoteFinishedResponse.roundFinished(); + } + return VoteFinishedResponse.allVoteFinished(isAllVoteFinished(room, balanceContent)); + } + + private boolean isRoundFinished(Room room, BalanceContent balanceContent) { + RoomContent roomContent = roomContentRepository.getByRoomAndBalanceContent(room, balanceContent); + roomContent.validateSameRound(room.getCurrentRound()); + roomContent.validateAlreadyUsed(); + return roomContent.isRoundOver(LocalDateTime.now(clock)); + } + + private boolean isAllVoteFinished(Room room, BalanceContent balanceContent) { + List balanceOptions = balanceOptionRepository.findAllByBalanceContent(balanceContent); + Long voteCount = balanceVoteRepository.countByMemberRoomAndBalanceOptionIn(room, balanceOptions); + List members = memberRepository.findAllByRoom(room); + return voteCount == members.size(); + } } diff --git a/backend/src/main/java/ddangkong/service/balance/vote/dto/VoteFinishedResponse.java b/backend/src/main/java/ddangkong/service/balance/vote/dto/VoteFinishedResponse.java new file mode 100644 index 00000000..13a3c31f --- /dev/null +++ b/backend/src/main/java/ddangkong/service/balance/vote/dto/VoteFinishedResponse.java @@ -0,0 +1,14 @@ +package ddangkong.service.balance.vote.dto; + +public record VoteFinishedResponse( + boolean isFinished +) { + + public static VoteFinishedResponse roundFinished() { + return new VoteFinishedResponse(true); + } + + public static VoteFinishedResponse allVoteFinished(boolean isAllVoteFinished) { + return new VoteFinishedResponse(isAllVoteFinished); + } +} diff --git a/backend/src/test/java/ddangkong/service/BaseServiceTest.java b/backend/src/test/java/ddangkong/service/BaseServiceTest.java index 1582b2d0..7be2f965 100644 --- a/backend/src/test/java/ddangkong/service/BaseServiceTest.java +++ b/backend/src/test/java/ddangkong/service/BaseServiceTest.java @@ -2,9 +2,16 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import ddangkong.domain.balance.content.BalanceContentRepository; +import ddangkong.domain.balance.option.BalanceOptionRepository; +import ddangkong.domain.balance.room.RoomContentRepository; +import ddangkong.domain.balance.room.RoomRepository; +import ddangkong.domain.balance.vote.BalanceVoteRepository; +import ddangkong.domain.member.MemberRepository; import ddangkong.support.extension.DatabaseCleanerExtension; import java.time.Clock; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.test.context.jdbc.Sql; @@ -14,4 +21,22 @@ @SpyBean(Clock.class) @Sql(scripts = "/init-test.sql") public abstract class BaseServiceTest { + + @Autowired + protected RoomRepository roomRepository; + + @Autowired + protected MemberRepository memberRepository; + + @Autowired + protected BalanceContentRepository balanceContentRepository; + + @Autowired + protected BalanceOptionRepository balanceOptionRepository; + + @Autowired + protected BalanceVoteRepository balanceVoteRepository; + + @Autowired + protected RoomContentRepository roomContentRepository; } diff --git a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java index 5b83e856..11cecf8f 100644 --- a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java @@ -1,5 +1,12 @@ package ddangkong.service.balance.vote; +import static ddangkong.support.fixture.MemberFixture.EDEN; +import static ddangkong.support.fixture.MemberFixture.KEOCHAN; +import static ddangkong.support.fixture.MemberFixture.MARU; +import static ddangkong.support.fixture.MemberFixture.POME; +import static ddangkong.support.fixture.MemberFixture.PRIN; +import static ddangkong.support.fixture.MemberFixture.SUNDAY; +import static ddangkong.support.fixture.MemberFixture.TACAN; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -10,10 +17,20 @@ import ddangkong.controller.balance.vote.dto.BalanceVoteRequest; import ddangkong.controller.balance.vote.dto.BalanceVoteResponse; import ddangkong.controller.balance.vote.dto.BalanceVoteResultResponse; +import ddangkong.domain.balance.content.BalanceContent; +import ddangkong.domain.balance.content.Category; +import ddangkong.domain.balance.option.BalanceOption; +import ddangkong.domain.balance.room.Room; +import ddangkong.domain.balance.room.RoomContent; +import ddangkong.domain.balance.vote.BalanceVote; +import ddangkong.domain.member.Member; import ddangkong.exception.BadRequestException; import ddangkong.service.BaseServiceTest; +import ddangkong.service.balance.vote.dto.VoteFinishedResponse; import ddangkong.support.annotation.FixedClock; +import java.time.LocalDateTime; import java.util.List; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -141,4 +158,132 @@ class 투표_결과_조회 { .isInstanceOf(BadRequestException.class); } } + + @Nested + @FixedClock(date = "2024-08-03", time = "11:00:00") + class 모두_투표했는지_조회 { + + private static final LocalDateTime ROUND_ENDED_AT = LocalDateTime.parse("2024-08-03T11:00:10"); + private static final boolean IS_USED = false; + + private Room myRoom; + + private BalanceContent aVsB; + + private BalanceOption optionA; + + private BalanceOption optionB; + + private Member prin; + + private Member tacan; + + private Member keochan; + + private Member eden; + + @BeforeEach + void setUp() { + aVsB = balanceContentRepository.save(new BalanceContent(Category.EXAMPLE, "A vs B")); + optionA = balanceOptionRepository.save(new BalanceOption("A", aVsB)); + optionB = balanceOptionRepository.save(new BalanceOption("B", aVsB)); + BalanceContent cVsD = balanceContentRepository.save(new BalanceContent(Category.EXAMPLE, "C vs D")); + BalanceOption optionC = balanceOptionRepository.save(new BalanceOption("C", cVsD)); + BalanceOption optionD = balanceOptionRepository.save(new BalanceOption("D", cVsD)); + + myRoom = roomRepository.save(Room.createNewRoom()); + prin = memberRepository.save(PRIN.master(myRoom)); + tacan = memberRepository.save(TACAN.common(myRoom)); + keochan = memberRepository.save(KEOCHAN.common(myRoom)); + eden = memberRepository.save(EDEN.common(myRoom)); + + Room anotherRoom = roomRepository.save(Room.createNewRoom()); + Member sunday = memberRepository.save(SUNDAY.master(anotherRoom)); + Member maru = memberRepository.save(MARU.common(anotherRoom)); + Member pome = memberRepository.save(POME.common(anotherRoom)); + + balanceVoteRepository.save(new BalanceVote(optionA, sunday)); + balanceVoteRepository.save(new BalanceVote(optionB, maru)); + balanceVoteRepository.save(new BalanceVote(optionC, prin)); + balanceVoteRepository.save(new BalanceVote(optionD, tacan)); + } + + @Test + void 방의_모든_멤버가_컨텐츠에_투표하면_모두_투표한_것이다() { + // given + int roomContentRound = 1; + roomContentRepository.save(new RoomContent(myRoom, aVsB, roomContentRound, ROUND_ENDED_AT, IS_USED)); + balanceVoteRepository.save(new BalanceVote(optionA, prin)); + balanceVoteRepository.save(new BalanceVote(optionA, tacan)); + balanceVoteRepository.save(new BalanceVote(optionB, keochan)); + balanceVoteRepository.save(new BalanceVote(optionB, eden)); + + // when + VoteFinishedResponse actual = balanceVoteService.getAllVoteFinished(myRoom.getId(), aVsB.getId()); + + // then + assertThat(actual.isFinished()).isTrue(); + } + + @Test + @FixedClock(date = "2024-08-03", time = "11:00:11") + void 컨텐츠의_투표_제한_시간이_지나면_모두_투표한_것이다() { + // given + int roomContentRound = 1; + roomContentRepository.save(new RoomContent(myRoom, aVsB, roomContentRound, ROUND_ENDED_AT, IS_USED)); + + // when + VoteFinishedResponse actual = balanceVoteService.getAllVoteFinished(myRoom.getId(), aVsB.getId()); + + // then + assertThat(actual.isFinished()).isTrue(); + } + + @Test + void 투표_제한_시간이_지나지_않고_방의_모든_멤버가_투표하지_않았으면_모두_투표하지_않은_것이다() { + // given + int roomContentRound = 1; + roomContentRepository.save(new RoomContent(myRoom, aVsB, roomContentRound, ROUND_ENDED_AT, IS_USED)); + balanceVoteRepository.save(new BalanceVote(optionA, prin)); + balanceVoteRepository.save(new BalanceVote(optionA, tacan)); + + // when + VoteFinishedResponse actual = balanceVoteService.getAllVoteFinished(myRoom.getId(), aVsB.getId()); + + // then + assertThat(actual.isFinished()).isFalse(); + } + + @Test + void 방에_존재하지_않은_방_컨텐츠이면_예외가_발생한다() { + // when & then + assertThatThrownBy(() -> balanceVoteService.getAllVoteFinished(myRoom.getId(), aVsB.getId())) + .isExactlyInstanceOf(BadRequestException.class) + .hasMessageContaining("방에 존재하지 않은 컨텐츠입니다."); + } + + @Test + void 방의_라운드와_방_컨텐츠의_라운드가_다르면_예외가_발생한다() { + // given + int roomContentRound = 2; + roomContentRepository.save(new RoomContent(myRoom, aVsB, roomContentRound, ROUND_ENDED_AT, IS_USED)); + + // when & then + assertThatThrownBy(() -> balanceVoteService.getAllVoteFinished(myRoom.getId(), aVsB.getId())) + .isExactlyInstanceOf(BadRequestException.class) + .hasMessageContaining("컨텐츠의 라운드가 일치하지 않습니다. 방 컨텐츠의 라운드 : 2, 요청한 라운드 : 1"); + } + + @Test + void 이미_사용된_방_컨텐츠이면_예외가_발생한다() { + // given + int roomContentRound = 1; + roomContentRepository.save(new RoomContent(myRoom, aVsB, roomContentRound, ROUND_ENDED_AT, true)); + + // when & then + assertThatThrownBy(() -> balanceVoteService.getAllVoteFinished(myRoom.getId(), aVsB.getId())) + .isExactlyInstanceOf(BadRequestException.class) + .hasMessageContaining("이미 사용된 컨텐츠입니다."); + } + } } diff --git a/backend/src/test/java/ddangkong/support/fixture/MemberFixture.java b/backend/src/test/java/ddangkong/support/fixture/MemberFixture.java new file mode 100644 index 00000000..d73b9250 --- /dev/null +++ b/backend/src/test/java/ddangkong/support/fixture/MemberFixture.java @@ -0,0 +1,23 @@ +package ddangkong.support.fixture; + +import ddangkong.domain.balance.room.Room; +import ddangkong.domain.member.Member; + +public enum MemberFixture { + PRIN, + TACAN, + KEOCHAN, + EDEN, + MARU, + POME, + SUNDAY, + ; + + public Member master(Room room) { + return Member.createMaster(name().toLowerCase(), room); + } + + public Member common(Room room) { + return Member.createCommon(name().toLowerCase(), room); + } +} From 484b53145fee0d3d43bc3779456601c5c93d31c9 Mon Sep 17 00:00:00 2001 From: useon Date: Sat, 3 Aug 2024 22:00:13 +0900 Subject: [PATCH 0498/1013] =?UTF-8?q?test:=20=ED=98=84=EC=9E=AC=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B4=EB=93=9C=20=EC=A2=85=EB=A3=8C=20=EC=97=AC?= =?UTF-8?q?=EB=B6=80=EB=A5=BC=20=ED=99=95=EC=9D=B8=ED=95=98=EB=8A=94=20msw?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/constants/url.ts | 1 + frontend/src/mocks/data/myGameStatus.json | 4 ++++ frontend/src/mocks/handlers/voteHandler.ts | 10 ++++++++++ 3 files changed, 15 insertions(+) create mode 100644 frontend/src/mocks/data/myGameStatus.json diff --git a/frontend/src/constants/url.ts b/frontend/src/constants/url.ts index b650db85..ff2a6762 100644 --- a/frontend/src/constants/url.ts +++ b/frontend/src/constants/url.ts @@ -16,6 +16,7 @@ export const MOCK_API_URL = { balanceContent: '/api/balances/rooms/:roomId/content', vote: '/api/balances/rooms/:roomId/contents/:contentId/votes', roundVoteResult: '/api/balances/rooms/:roomId/contents/:contentId/vote-result', + myGameStatus: '/api/balances/rooms/:roomId?myRound=:myRound', moveNextRound: '/api/balances/rooms/:roomId/contents', finalResult: '/api/balances/rooms/:roomId/final', }; diff --git a/frontend/src/mocks/data/myGameStatus.json b/frontend/src/mocks/data/myGameStatus.json new file mode 100644 index 00000000..3ce29dc8 --- /dev/null +++ b/frontend/src/mocks/data/myGameStatus.json @@ -0,0 +1,4 @@ +{ + "isRoundFinished": false, + "isGameFinished": false +} diff --git a/frontend/src/mocks/handlers/voteHandler.ts b/frontend/src/mocks/handlers/voteHandler.ts index 788c20a4..c3f94383 100644 --- a/frontend/src/mocks/handlers/voteHandler.ts +++ b/frontend/src/mocks/handlers/voteHandler.ts @@ -2,6 +2,7 @@ import { http, HttpResponse } from 'msw'; import BALANCE_CONTENT from '../data/balanceContent.json'; import FINAL_RESULT from '../data/finalResult.json'; +import MY_GAME_STATUS from '../data/myGameStatus.json'; import VOTE_RESULT from '../data/roundVoteResult.json'; import { MOCK_API_URL } from '@/constants/url'; @@ -33,9 +34,18 @@ const fetchFinalResultHandler = async () => { return HttpResponse.json(FINAL_RESULT); }; +const checkMyGameStatusHandler = () => { + setTimeout(() => { + MY_GAME_STATUS.isRoundFinished = true; + }, 5 * 1000); + + return HttpResponse.json(MY_GAME_STATUS); +}; + export const voteHandler = [ http.post(MOCK_API_URL.vote, voteBalanceContentHandler), http.get(MOCK_API_URL.roundVoteResult, fetchVoteResultHandler), + http.get(MOCK_API_URL.myGameStatus, checkMyGameStatusHandler), http.post(MOCK_API_URL.moveNextRound, goToNextRoundHandler), http.get(MOCK_API_URL.finalResult, fetchFinalResultHandler), ]; From e1a32cc111cb99477b2a1821c90bcb655509b8c4 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Sat, 3 Aug 2024 22:04:40 +0900 Subject: [PATCH 0499/1013] =?UTF-8?q?refactor:=20repository=20test?= =?UTF-8?q?=EC=97=90=EC=84=9C=20sql=20script=20=EC=A0=9C=EA=B1=B0=20#58?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ddangkong/domain/BaseRepositoryTest.java | 18 +++++++++-- .../room/RoomContentRepositoryTest.java | 31 +++++++++++++------ 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/backend/src/test/java/ddangkong/domain/BaseRepositoryTest.java b/backend/src/test/java/ddangkong/domain/BaseRepositoryTest.java index 19bf3261..4109ee83 100644 --- a/backend/src/test/java/ddangkong/domain/BaseRepositoryTest.java +++ b/backend/src/test/java/ddangkong/domain/BaseRepositoryTest.java @@ -1,12 +1,26 @@ package ddangkong.domain; import ddangkong.config.JpaAuditingConfig; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.Import; -import org.springframework.test.context.jdbc.Sql; @DataJpaTest @Import(JpaAuditingConfig.class) -@Sql(scripts = "/init-test.sql") public abstract class BaseRepositoryTest { + + @PersistenceContext + private EntityManager em; + + protected T save(T entity) { + em.persist(entity); + flushAndClear(); + return entity; + } + + private void flushAndClear() { + em.flush(); + em.clear(); + } } diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomContentRepositoryTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomContentRepositoryTest.java index 6fceccd2..9387e690 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomContentRepositoryTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomContentRepositoryTest.java @@ -3,6 +3,10 @@ import static org.assertj.core.api.Assertions.assertThat; import ddangkong.domain.BaseRepositoryTest; +import ddangkong.domain.balance.content.BalanceContent; +import ddangkong.domain.balance.content.Category; +import java.time.LocalDateTime; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -12,24 +16,33 @@ class RoomContentRepositoryTest extends BaseRepositoryTest { @Autowired private RoomContentRepository roomContentRepository; - @Autowired - private RoomRepository roomRepository; - @Nested class 방의_해당_라운드_질문_조회 { + private static final LocalDateTime ROUND_ENDED_AT = LocalDateTime.parse("2021-08-03T00:00:00"); + + private Room room; + + private BalanceContent balanceContent; + + @BeforeEach + void setUp() { + room = save(Room.createNewRoom()); + balanceContent = save(new BalanceContent(Category.EXAMPLE, "A vs B")); + } + @Test - void 방의_해당_라운드의_질문을_조회할_수_있다() { + void 방의_현재_라운드에_해당하는_룸_컨텐츠를_조회할_수_있다() { // given - Long roomId = 1L; - Room room = roomRepository.findById(roomId).get(); - int round = 2; + int round = 1; + RoomContent roomContent = new RoomContent(room, balanceContent, round, ROUND_ENDED_AT, false); + roomContentRepository.save(roomContent); // when - RoomContent actual = roomContentRepository.findByRoomAndRound(room, round).get(); + RoomContent actual = roomContentRepository.findByRoomAndRound(room, room.getCurrentRound()).orElseThrow(); // then - assertThat(actual.getId()).isEqualTo(2L); + assertThat(actual.getId()).isEqualTo(1L); } } } From ecf151bd1f28fc8d7ac601220affd99b926d9098 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Sat, 3 Aug 2024 22:20:39 +0900 Subject: [PATCH 0500/1013] =?UTF-8?q?refactor:=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=EB=AA=85=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81=20#58?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../balance/vote/BalanceVoteServiceTest.java | 33 ++++++------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java index 11cecf8f..c668fdf8 100644 --- a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java @@ -2,10 +2,7 @@ import static ddangkong.support.fixture.MemberFixture.EDEN; import static ddangkong.support.fixture.MemberFixture.KEOCHAN; -import static ddangkong.support.fixture.MemberFixture.MARU; -import static ddangkong.support.fixture.MemberFixture.POME; import static ddangkong.support.fixture.MemberFixture.PRIN; -import static ddangkong.support.fixture.MemberFixture.SUNDAY; import static ddangkong.support.fixture.MemberFixture.TACAN; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -161,7 +158,7 @@ class 투표_결과_조회 { @Nested @FixedClock(date = "2024-08-03", time = "11:00:00") - class 모두_투표했는지_조회 { + class 투표_종료_여부_조회 { private static final LocalDateTime ROUND_ENDED_AT = LocalDateTime.parse("2024-08-03T11:00:10"); private static final boolean IS_USED = false; @@ -187,25 +184,12 @@ void setUp() { aVsB = balanceContentRepository.save(new BalanceContent(Category.EXAMPLE, "A vs B")); optionA = balanceOptionRepository.save(new BalanceOption("A", aVsB)); optionB = balanceOptionRepository.save(new BalanceOption("B", aVsB)); - BalanceContent cVsD = balanceContentRepository.save(new BalanceContent(Category.EXAMPLE, "C vs D")); - BalanceOption optionC = balanceOptionRepository.save(new BalanceOption("C", cVsD)); - BalanceOption optionD = balanceOptionRepository.save(new BalanceOption("D", cVsD)); myRoom = roomRepository.save(Room.createNewRoom()); prin = memberRepository.save(PRIN.master(myRoom)); tacan = memberRepository.save(TACAN.common(myRoom)); keochan = memberRepository.save(KEOCHAN.common(myRoom)); eden = memberRepository.save(EDEN.common(myRoom)); - - Room anotherRoom = roomRepository.save(Room.createNewRoom()); - Member sunday = memberRepository.save(SUNDAY.master(anotherRoom)); - Member maru = memberRepository.save(MARU.common(anotherRoom)); - Member pome = memberRepository.save(POME.common(anotherRoom)); - - balanceVoteRepository.save(new BalanceVote(optionA, sunday)); - balanceVoteRepository.save(new BalanceVote(optionB, maru)); - balanceVoteRepository.save(new BalanceVote(optionC, prin)); - balanceVoteRepository.save(new BalanceVote(optionD, tacan)); } @Test @@ -226,11 +210,12 @@ void setUp() { } @Test - @FixedClock(date = "2024-08-03", time = "11:00:11") + @FixedClock(date = "2024-08-03", time = "11:00:21") void 컨텐츠의_투표_제한_시간이_지나면_모두_투표한_것이다() { // given int roomContentRound = 1; - roomContentRepository.save(new RoomContent(myRoom, aVsB, roomContentRound, ROUND_ENDED_AT, IS_USED)); + LocalDateTime roundEndedAt = LocalDateTime.parse("2024-08-03T11:00:20"); + roomContentRepository.save(new RoomContent(myRoom, aVsB, roomContentRound, roundEndedAt, IS_USED)); // when VoteFinishedResponse actual = balanceVoteService.getAllVoteFinished(myRoom.getId(), aVsB.getId()); @@ -246,6 +231,7 @@ void setUp() { roomContentRepository.save(new RoomContent(myRoom, aVsB, roomContentRound, ROUND_ENDED_AT, IS_USED)); balanceVoteRepository.save(new BalanceVote(optionA, prin)); balanceVoteRepository.save(new BalanceVote(optionA, tacan)); + balanceVoteRepository.save(new BalanceVote(optionB, eden)); // when VoteFinishedResponse actual = balanceVoteService.getAllVoteFinished(myRoom.getId(), aVsB.getId()); @@ -255,7 +241,7 @@ void setUp() { } @Test - void 방에_존재하지_않은_방_컨텐츠이면_예외가_발생한다() { + void 방에_존재하지_않은_방_컨텐츠의_투표_여부를_조회하면_예외가_발생한다() { // when & then assertThatThrownBy(() -> balanceVoteService.getAllVoteFinished(myRoom.getId(), aVsB.getId())) .isExactlyInstanceOf(BadRequestException.class) @@ -263,7 +249,7 @@ void setUp() { } @Test - void 방의_라운드와_방_컨텐츠의_라운드가_다르면_예외가_발생한다() { + void 방의_현재_라운드와_다른_방_컨텐츠의_투표_여부를_조회하면_예외가_발생한다() { // given int roomContentRound = 2; roomContentRepository.save(new RoomContent(myRoom, aVsB, roomContentRound, ROUND_ENDED_AT, IS_USED)); @@ -275,10 +261,11 @@ void setUp() { } @Test - void 이미_사용된_방_컨텐츠이면_예외가_발생한다() { + void 이미_사용된_방_컨텐츠의_투표_여부를_조회하면_예외가_발생한다() { // given int roomContentRound = 1; - roomContentRepository.save(new RoomContent(myRoom, aVsB, roomContentRound, ROUND_ENDED_AT, true)); + boolean isUsed = true; + roomContentRepository.save(new RoomContent(myRoom, aVsB, roomContentRound, ROUND_ENDED_AT, isUsed)); // when & then assertThatThrownBy(() -> balanceVoteService.getAllVoteFinished(myRoom.getId(), aVsB.getId())) From fbe16ea4adcad7dd9355c9d4bf32a193aa0efd37 Mon Sep 17 00:00:00 2001 From: useon Date: Sat, 3 Aug 2024 22:21:17 +0900 Subject: [PATCH 0501/1013] =?UTF-8?q?refactor:=20=EB=91=90=20=EA=B3=B3=20?= =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=97=90=EC=84=9C=20=EC=93=B0=EC=9D=B4?= =?UTF-8?q?=EB=8A=94=20=EB=9D=BC=EC=9A=B4=EB=93=9C=20=EC=A2=85=EB=A3=8C=20?= =?UTF-8?q?=EB=B0=8F=20=EA=B2=8C=EC=9E=84=20=EC=A2=85=EB=A3=8C=20=EC=97=AC?= =?UTF-8?q?=EB=B6=80=20=ED=99=95=EC=9D=B8=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=ED=9B=85=20=EB=B6=84=EB=A6=AC=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../useMyGameStatus.ts} | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) rename frontend/src/{components/OptionParticipantsContainer/OptionParticipantsContainer.hook.ts => hooks/useMyGameStatus.ts} (71%) diff --git a/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.hook.ts b/frontend/src/hooks/useMyGameStatus.ts similarity index 71% rename from frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.hook.ts rename to frontend/src/hooks/useMyGameStatus.ts index c2d88a10..81259097 100644 --- a/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.hook.ts +++ b/frontend/src/hooks/useMyGameStatus.ts @@ -1,21 +1,22 @@ import { useEffect } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; +import useBalanceContentQuery from './useBalanceContentQuery'; +import useMyGameStatusQuery from './useMyGameStatusQuery'; +import useRoundVoteResultQuery from './useRoundVoteResultQuery'; + import { ROUTES } from '@/constants/routes'; -import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; -import useMyGameStatusQuery from '@/hooks/useMyGameStatusQuery'; -import useRoundVoteResultQuery from '@/hooks/useRoundVoteResultQuery'; -const useOptionParticipants = () => { +const useMyGameStatus = () => { const { search } = useLocation(); const roomId = Number(new URLSearchParams(search).get('roomId')); const navigate = useNavigate(); const { balanceContent } = useBalanceContentQuery(); - const { groupRoundResult } = useRoundVoteResultQuery({ - contentId: balanceContent?.contentId, + const { groupRoundResult, totalResult } = useRoundVoteResultQuery({ roomId: roomId, + contentId: balanceContent?.contentId, }); const { isRoundFinished, isGameFinished } = useMyGameStatusQuery({ balanceContent, roomId }); @@ -39,7 +40,8 @@ const useOptionParticipants = () => { return { groupRoundResult, + totalResult, }; }; -export default useOptionParticipants; +export default useMyGameStatus; From 3b9335f3dead295072d0ea8109767f9e25c5a34e Mon Sep 17 00:00:00 2001 From: useon Date: Sat, 3 Aug 2024 22:22:43 +0900 Subject: [PATCH 0502/1013] =?UTF-8?q?feat:=20useMyGameStatus=20=EC=BB=A4?= =?UTF-8?q?=EC=8A=A4=ED=85=80=20=ED=9B=85=20=ED=88=AC=ED=91=9C=20=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=82=B4=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8,=20=ED=88=AC=ED=91=9C=20=ED=98=84?= =?UTF-8?q?=ED=99=A9=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=82=B4=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=97=90=20=EC=A0=81=EC=9A=A9=20#10?= =?UTF-8?q?6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OptionParticipantsContainer.tsx | 5 +++-- .../RoundVoteContainer/RoundVoteContainer.tsx | 10 ++-------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx index 06402451..3445305b 100644 --- a/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx +++ b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx @@ -1,4 +1,3 @@ -import useOptionParticipantsQuery from './OptionParticipantsContainer.hook'; import { dividerLine, optionParticipantsContainerLayout, @@ -6,8 +5,10 @@ import { import OptionParticipants from '../OptionParticipants/OptionParticipants'; import TopicContainer from '../TopicContainer/TopicContainer'; +import useMyGameStatus from '@/hooks/useMyGameStatus'; + const OptionParticipantsContainer = () => { - const { groupRoundResult } = useOptionParticipantsQuery(); + const { groupRoundResult } = useMyGameStatus(); if (!groupRoundResult) { return null; diff --git a/frontend/src/components/RoundVoteContainer/RoundVoteContainer.tsx b/frontend/src/components/RoundVoteContainer/RoundVoteContainer.tsx index 12129946..b6a574c3 100644 --- a/frontend/src/components/RoundVoteContainer/RoundVoteContainer.tsx +++ b/frontend/src/components/RoundVoteContainer/RoundVoteContainer.tsx @@ -5,18 +5,12 @@ import { tabLayout, tabWrapper } from './RoundVoteContainer.styled'; import RoundResultTab from '../RoundResultTab/RoundResultTab'; import TabContentContainer from '../TabContentContainer/TabContentContainer'; -import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; -import useRoundVoteResultQuery from '@/hooks/useRoundVoteResultQuery'; +import useMyGameStatus from '@/hooks/useMyGameStatus'; const RoundVoteContainer = () => { const [activeTab, setActiveTab] = useState<'group' | 'total'>('group'); const isGroupTabActive = activeTab === 'group'; - - const { balanceContent } = useBalanceContentQuery(); - const { groupRoundResult, totalResult } = useRoundVoteResultQuery({ - roomId: 1, - contentId: balanceContent?.contentId, - }); + const { groupRoundResult, totalResult } = useMyGameStatus(); const { animatedFirstPercent, From 00f1adee234017c52c9ce80d86573199f213e81c Mon Sep 17 00:00:00 2001 From: useon Date: Sat, 3 Aug 2024 22:44:41 +0900 Subject: [PATCH 0503/1013] =?UTF-8?q?feat:=20=EB=B0=A9=EC=9E=A5=EB=A7=8C?= =?UTF-8?q?=20=EB=8B=A4=EC=9D=8C=20=EB=98=90=EB=8A=94=20=EA=B2=B0=EA=B3=BC?= =?UTF-8?q?=20=ED=99=95=EC=9D=B8=20=EB=B2=84=ED=8A=BC=EC=9D=B4=20=ED=99=9C?= =?UTF-8?q?=EC=84=B1=ED=99=94=EB=90=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20#10?= =?UTF-8?q?6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/common/NextRoundButton/NextRoundButton.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx index 531cd275..2fb0498e 100644 --- a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx +++ b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx @@ -1,17 +1,21 @@ import { useNavigate } from 'react-router-dom'; +import { useRecoilValue } from 'recoil'; import { useMoveNextRoundMutation } from './NextRoundButton.hook'; import Button from '../Button/Button'; import { bottomButtonLayout } from '../Button/Button.styled'; import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; +import { memberInfoState } from '@/recoil/atom'; const NextRoundButton = () => { const navigate = useNavigate(); const { balanceContent } = useBalanceContentQuery(); const { mutateAsync: moveNextRound } = useMoveNextRoundMutation(); + const memberInfo = useRecoilValue(memberInfoState); const isLastRound = balanceContent?.currentRound === balanceContent?.totalRound; + const isButtonDisabled = !memberInfo.isMaster; const goToGameResult = () => { navigate('/game/result'); @@ -28,6 +32,7 @@ const NextRoundButton = () => { style={{ width: '100%' }} text={isLastRound ? '결과 확인' : '다음'} onClick={isLastRound ? goToGameResult : goToNextRound} + disabled={isButtonDisabled} />
    ); From e3b61a97b9cab45e1d1dfb20d3f5070222ebb308 Mon Sep 17 00:00:00 2001 From: useon Date: Sat, 3 Aug 2024 22:49:53 +0900 Subject: [PATCH 0504/1013] =?UTF-8?q?refactor:=20=EB=8B=A4=EC=9D=8C=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B4=EB=93=9C=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=ED=95=98=EB=8A=94=20api=20=EC=88=98=EC=A0=95=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/balanceContent.ts | 4 ++-- frontend/src/constants/url.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/apis/balanceContent.ts b/frontend/src/apis/balanceContent.ts index a534d507..4090de87 100644 --- a/frontend/src/apis/balanceContent.ts +++ b/frontend/src/apis/balanceContent.ts @@ -76,8 +76,8 @@ export const checkMyGameStatus = async ({ }; // 다음 라운드로 이동하기 -export const moveNextRound = async (roomId = 1): Promise => { - const res = await fetcher.post({ +export const moveNextRound = async (roomId: number): Promise => { + const res = await fetcher.patch({ url: API_URL.moveNextRound(roomId), headers: { 'Content-Type': `application/json`, diff --git a/frontend/src/constants/url.ts b/frontend/src/constants/url.ts index ff2a6762..c9e8a0e3 100644 --- a/frontend/src/constants/url.ts +++ b/frontend/src/constants/url.ts @@ -6,7 +6,7 @@ export const API_URL = { `${BASE_URL}/api/balances/rooms/${roomId}/contents/${contentId}/votes`, roundVoteResult: (roomId: number, contentId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/contents/${contentId}/vote-result`, - moveNextRound: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/contents`, + moveNextRound: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/next-round`, myGameStatus: (roomId: number, round: number) => `${BASE_URL}/api/balances/rooms/${roomId}?round=${round}`, finalResult: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/final`, From e1b3ee65f79728fe86dcc4ae9f1bbaa51431e4d1 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Sat, 3 Aug 2024 22:51:32 +0900 Subject: [PATCH 0505/1013] =?UTF-8?q?refactor:=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=EB=AA=85=20=ED=86=B5=EC=9D=BC=EC=84=B1=EC=9D=84=20?= =?UTF-8?q?=EC=9C=84=ED=95=B4=20=EB=B3=80=EA=B2=BD=20#58?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ddangkong/service/balance/vote/BalanceVoteServiceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java index c668fdf8..01fe23f2 100644 --- a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java @@ -225,7 +225,7 @@ void setUp() { } @Test - void 투표_제한_시간이_지나지_않고_방의_모든_멤버가_투표하지_않았으면_모두_투표하지_않은_것이다() { + void 투표_제한_시간이_끝나지_않고_방의_모든_멤버가_투표하지_않았으면_모두_투표하지_않은_것이다() { // given int roomContentRound = 1; roomContentRepository.save(new RoomContent(myRoom, aVsB, roomContentRound, ROUND_ENDED_AT, IS_USED)); From 4acaefd4c236e05378a2cc7679d2d497928c116d Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Sat, 3 Aug 2024 22:52:09 +0900 Subject: [PATCH 0506/1013] =?UTF-8?q?refactor:=20=EB=AA=A8=EB=93=A0=20?= =?UTF-8?q?=ED=88=AC=ED=91=9C=EA=B0=80=20=EB=81=9D=EB=82=AC=EB=8A=94?= =?UTF-8?q?=EC=A7=80=20=ED=99=95=EC=9D=B8=ED=95=98=EB=8A=94=20api=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#58?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../balance/vote/BalanceVoteController.java | 9 +- .../balance/vote/BalanceVoteRepository.java | 2 + .../controller/BaseControllerTest.java | 27 +++- .../vote/BalanceVoteControllerTest.java | 144 ++++++++++++++++-- 4 files changed, 165 insertions(+), 17 deletions(-) diff --git a/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java b/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java index 26759f23..daf119e7 100644 --- a/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java +++ b/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java @@ -1,9 +1,10 @@ package ddangkong.controller.balance.vote; -import ddangkong.controller.balance.vote.dto.BalanceVoteResultResponse; import ddangkong.controller.balance.vote.dto.BalanceVoteRequest; import ddangkong.controller.balance.vote.dto.BalanceVoteResponse; +import ddangkong.controller.balance.vote.dto.BalanceVoteResultResponse; import ddangkong.service.balance.vote.BalanceVoteService; +import ddangkong.service.balance.vote.dto.VoteFinishedResponse; import jakarta.validation.Valid; import jakarta.validation.constraints.Positive; import lombok.RequiredArgsConstructor; @@ -38,4 +39,10 @@ public BalanceVoteResponse createBalanceVote(@PathVariable @Positive Long roomId @RequestBody @Valid BalanceVoteRequest request) { return balanceVoteService.createBalanceVote(request, roomId, contentId); } + + @GetMapping("/balances/rooms/{roomId}/contents/{contentId}/vote-finished") + public VoteFinishedResponse getAllVoteFinished(@PathVariable @Positive Long roomId, + @PathVariable @Positive Long contentId) { + return balanceVoteService.getAllVoteFinished(roomId, contentId); + } } diff --git a/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVoteRepository.java b/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVoteRepository.java index 6a087421..f654f567 100644 --- a/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVoteRepository.java +++ b/backend/src/main/java/ddangkong/domain/balance/vote/BalanceVoteRepository.java @@ -9,4 +9,6 @@ public interface BalanceVoteRepository extends JpaRepository Long countByBalanceOption(BalanceOption balanceOption); List findByMemberRoomAndBalanceOption(Room room, BalanceOption balanceOption); + + Long countByMemberRoomAndBalanceOptionIn(Room room, List balanceOptions); } diff --git a/backend/src/test/java/ddangkong/controller/BaseControllerTest.java b/backend/src/test/java/ddangkong/controller/BaseControllerTest.java index 5fe0f5e6..1aff11f1 100644 --- a/backend/src/test/java/ddangkong/controller/BaseControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/BaseControllerTest.java @@ -3,11 +3,18 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import ddangkong.domain.balance.content.BalanceContentRepository; +import ddangkong.domain.balance.option.BalanceOptionRepository; +import ddangkong.domain.balance.room.RoomContentRepository; +import ddangkong.domain.balance.room.RoomRepository; +import ddangkong.domain.balance.vote.BalanceVoteRepository; +import ddangkong.domain.member.MemberRepository; import ddangkong.support.extension.DatabaseCleanerExtension; import io.restassured.RestAssured; import java.time.Clock; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.boot.test.web.server.LocalServerPort; @@ -19,11 +26,29 @@ @Sql(scripts = "/init-test.sql") public abstract class BaseControllerTest { + @Autowired + protected RoomRepository roomRepository; + + @Autowired + protected MemberRepository memberRepository; + + @Autowired + protected BalanceContentRepository balanceContentRepository; + + @Autowired + protected BalanceOptionRepository balanceOptionRepository; + + @Autowired + protected BalanceVoteRepository balanceVoteRepository; + + @Autowired + protected RoomContentRepository roomContentRepository; + @LocalServerPort private int port; @BeforeEach - void setUp() { + void setUpPort() { RestAssured.port = port; } } diff --git a/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java index 394f8f50..ed215c2d 100644 --- a/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java @@ -1,68 +1,114 @@ package ddangkong.controller.balance.vote; +import static ddangkong.support.fixture.MemberFixture.EDEN; +import static ddangkong.support.fixture.MemberFixture.KEOCHAN; +import static ddangkong.support.fixture.MemberFixture.PRIN; +import static ddangkong.support.fixture.MemberFixture.TACAN; import static org.assertj.core.api.Assertions.assertThat; import ddangkong.controller.BaseControllerTest; import ddangkong.controller.balance.vote.dto.BalanceVoteRequest; import ddangkong.controller.balance.vote.dto.BalanceVoteResponse; +import ddangkong.domain.balance.content.BalanceContent; +import ddangkong.domain.balance.content.Category; +import ddangkong.domain.balance.option.BalanceOption; +import ddangkong.domain.balance.room.Room; +import ddangkong.domain.balance.room.RoomContent; +import ddangkong.domain.balance.vote.BalanceVote; +import ddangkong.domain.member.Member; +import ddangkong.service.balance.vote.dto.VoteFinishedResponse; import ddangkong.support.annotation.FixedClock; import io.restassured.RestAssured; import io.restassured.http.ContentType; +import java.time.LocalDateTime; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; class BalanceVoteControllerTest extends BaseControllerTest { + private Room room; + + private BalanceContent balanceContent; + + private BalanceOption optionA; + + private BalanceOption optionB; + + private Member prin; + + private Member tacan; + + private Member keochan; + + private Member eden; + + @BeforeEach + void setUp() { + balanceContent = balanceContentRepository.save(new BalanceContent(Category.EXAMPLE, "A vs B")); + optionA = balanceOptionRepository.save(new BalanceOption("A", balanceContent)); + optionB = balanceOptionRepository.save(new BalanceOption("B", balanceContent)); + + room = roomRepository.save(Room.createNewRoom()); + prin = memberRepository.save(PRIN.master(room)); + tacan = memberRepository.save(TACAN.common(room)); + keochan = memberRepository.save(KEOCHAN.common(room)); + eden = memberRepository.save(EDEN.common(room)); + } + @Nested @FixedClock(date = "2024-07-18", time = "20:00:02") class 투표_생성 { - private static final Long ROOM_ID = 1L; - private static final Long CONTENT_ID = 1L; - private static final BalanceVoteRequest NORMAL_REQUEST = new BalanceVoteRequest(1L, 1L); - private static final BalanceVoteResponse EXPECTED_RESPONSE = new BalanceVoteResponse(1L); - @Test void 현재_방에서_투표할_수_있다() { - // given & when + // given + LocalDateTime roundEndedAt = LocalDateTime.parse("2024-07-18T20:00:08"); + roomContentRepository.save(new RoomContent(room, balanceContent, 1, roundEndedAt, false)); + + BalanceVoteRequest request = new BalanceVoteRequest(keochan.getId(), optionA.getId()); + + // when BalanceVoteResponse actual = RestAssured.given().log().all() - .body(NORMAL_REQUEST).contentType(ContentType.JSON) - .pathParam("roomId", ROOM_ID) - .pathParam("contentId", CONTENT_ID) + .body(request) + .contentType(ContentType.JSON) + .pathParam("roomId", room.getId()) + .pathParam("contentId", balanceContent.getId()) .when().post("/api/balances/rooms/{roomId}/contents/{contentId}/votes") .then().log().all() .statusCode(201) .extract().as(BalanceVoteResponse.class); // then - assertThat(actual).isEqualTo(EXPECTED_RESPONSE); + assertThat(actual.optionId()).isEqualTo(optionA.getId()); } @Test void 요청_경로의_아이디가_양수가_아닌_경우_400_에러로_응답한다() { // given + BalanceVoteRequest request = new BalanceVoteRequest(keochan.getId(), optionA.getId()); Long roomId = 0L; // when & then - assertThatCreateVoteIsBadRequest(roomId, CONTENT_ID, NORMAL_REQUEST); + assertThatCreateVoteIsBadRequest(roomId, balanceContent.getId(), request); } @Test void 요청_바디의_아이디가_양수가_아닌_경우_400_에러로_응답한다() { // given - BalanceVoteRequest request = new BalanceVoteRequest(0L, 1L); + BalanceVoteRequest request = new BalanceVoteRequest(0L, optionA.getId()); // when & then - assertThatCreateVoteIsBadRequest(ROOM_ID, CONTENT_ID, request); + assertThatCreateVoteIsBadRequest(room.getId(), balanceContent.getId(), request); } @Test void 요청_바디의_아이디가_null인_경우_400_에러로_응답한다() { // given - BalanceVoteRequest request = new BalanceVoteRequest(null, 1L); + BalanceVoteRequest request = new BalanceVoteRequest(null, optionA.getId()); // when & then - assertThatCreateVoteIsBadRequest(ROOM_ID, CONTENT_ID, request); + assertThatCreateVoteIsBadRequest(room.getId(), balanceContent.getId(), request); } void assertThatCreateVoteIsBadRequest(Long roomId, Long contentId, BalanceVoteRequest request) { @@ -75,4 +121,72 @@ void assertThatCreateVoteIsBadRequest(Long roomId, Long contentId, BalanceVoteRe .statusCode(400); } } + + @Nested + @FixedClock(date = "2024-08-03", time = "20:00:02") + class 투표_종료_여부_조회 { + + private static final String ENDPOINT = "/api/balances/rooms/{roomId}/contents/{contentId}/vote-finished"; + + @Test + void 방의_모든_멤버가_투표하면_투표가_종료된다() { + // given + LocalDateTime roundEndedAt = LocalDateTime.parse("2024-08-03T20:00:08"); + roomContentRepository.save(new RoomContent(room, balanceContent, 1, roundEndedAt, false)); + balanceVoteRepository.save(new BalanceVote(optionA, prin)); + balanceVoteRepository.save(new BalanceVote(optionA, tacan)); + balanceVoteRepository.save(new BalanceVote(optionB, keochan)); + balanceVoteRepository.save(new BalanceVote(optionB, eden)); + + // when + VoteFinishedResponse actual = RestAssured.given().log().all() + .pathParam("roomId", room.getId()) + .pathParam("contentId", balanceContent.getId()) + .when().get(ENDPOINT) + .then().log().all() + .statusCode(200) + .extract().as(VoteFinishedResponse.class); + + // then + assertThat(actual.isFinished()).isEqualTo(true); + } + + @Test + void 방_컨텐츠의_투표_제한_시간이_끝나면_투표가_종료된다() { + // given + LocalDateTime roundEndedAt = LocalDateTime.parse("2024-08-03T20:00:00"); + roomContentRepository.save(new RoomContent(room, balanceContent, 1, roundEndedAt, false)); + + // when + VoteFinishedResponse actual = RestAssured.given().log().all() + .pathParam("roomId", room.getId()) + .pathParam("contentId", balanceContent.getId()) + .when().get(ENDPOINT) + .then().log().all() + .statusCode(200) + .extract().as(VoteFinishedResponse.class); + + // then + assertThat(actual.isFinished()).isEqualTo(true); + } + + @Test + void 투표_제한_시간이_끝나지_않고_방의_모든_멤버가_투표하지_않으면_투표가_종료되지_않는다() { + // given + LocalDateTime roundEndedAt = LocalDateTime.parse("2024-08-03T20:00:08"); + roomContentRepository.save(new RoomContent(room, balanceContent, 1, roundEndedAt, false)); + + // when + VoteFinishedResponse actual = RestAssured.given().log().all() + .pathParam("roomId", room.getId()) + .pathParam("contentId", balanceContent.getId()) + .when().get(ENDPOINT) + .then().log().all() + .statusCode(200) + .extract().as(VoteFinishedResponse.class); + + // then + assertThat(actual.isFinished()).isEqualTo(false); + } + } } From 616d1cb218e102441639e61287b7b9d67596504d Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Sat, 3 Aug 2024 22:56:53 +0900 Subject: [PATCH 0507/1013] =?UTF-8?q?test:=20=EB=AA=A8=EB=93=A0=20?= =?UTF-8?q?=ED=88=AC=ED=91=9C=EA=B0=80=20=EB=81=9D=EB=82=AC=EB=8A=94?= =?UTF-8?q?=EC=A7=80=20=ED=99=95=EC=9D=B8=ED=95=98=EB=8A=94=20api=20?= =?UTF-8?q?=EB=AC=B8=EC=84=9C=20=EC=B6=94=EA=B0=80=20#58?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/docs/asciidoc/balanceVote.adoc | 20 +++++++++++++ .../vote/BalanceVoteDocumentationTest.java | 30 +++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/backend/src/docs/asciidoc/balanceVote.adoc b/backend/src/docs/asciidoc/balanceVote.adoc index 58ccd2a3..38857a98 100644 --- a/backend/src/docs/asciidoc/balanceVote.adoc +++ b/backend/src/docs/asciidoc/balanceVote.adoc @@ -43,3 +43,23 @@ include::{snippets}/balanceVote/createBalanceVote/http-response.adoc[] response fields include::{snippets}/balanceVote/createBalanceVote/response-fields.adoc[] + +=== 투표 종료 여부 + +==== curl + +include::{snippets}/balanceVote/voteFinished/curl-request.adoc[] + +==== request + +include::{snippets}/balanceVote/voteFinished/http-request.adoc[] + +include::{snippets}/balanceVote/voteFinished/path-parameters.adoc[] + +==== response + +include::{snippets}/balanceVote/voteFinished/http-response.adoc[] + +response fields + +include::{snippets}/balanceVote/voteFinished/response-fields.adoc[] diff --git a/backend/src/test/java/ddangkong/documentation/balance/vote/BalanceVoteDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/vote/BalanceVoteDocumentationTest.java index ccc3d2e1..b114dd50 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/vote/BalanceVoteDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/vote/BalanceVoteDocumentationTest.java @@ -1,10 +1,12 @@ package ddangkong.documentation.balance.vote; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.when; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; import static org.springframework.restdocs.payload.JsonFieldType.ARRAY; +import static org.springframework.restdocs.payload.JsonFieldType.BOOLEAN; import static org.springframework.restdocs.payload.JsonFieldType.NUMBER; import static org.springframework.restdocs.payload.JsonFieldType.OBJECT; import static org.springframework.restdocs.payload.JsonFieldType.STRING; @@ -25,6 +27,7 @@ import ddangkong.controller.balance.vote.dto.BalanceVoteResultResponse; import ddangkong.documentation.BaseDocumentationTest; import ddangkong.service.balance.vote.BalanceVoteService; +import ddangkong.service.balance.vote.dto.VoteFinishedResponse; import java.util.List; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -141,4 +144,31 @@ class 투표_생성 { ); } } + + @Nested + class 투표_종료_여부_조회 { + + private static final String END_POINT = "/api/balances/rooms/{roomId}/contents/{contentId}/vote-finished"; + + @Test + void 투표가_종료되었는지_조회한다() throws Exception { + // given + VoteFinishedResponse response = new VoteFinishedResponse(true); + when(balanceVoteService.getAllVoteFinished(anyLong(), anyLong())).thenReturn(response); + + // when & then + mockMvc.perform(get(END_POINT, 1L, 1L)) + .andExpect(status().isOk()) + .andDo(document("balanceVote/voteFinished", + pathParameters( + parameterWithName("roomId").description("방 ID"), + parameterWithName("contentId").description("콘텐츠 ID") + ), + responseFields( + fieldWithPath("isFinished").type(BOOLEAN).description("투표 종료 여부") + ) + ) + ); + } + } } From 7571bad8e7d6716aedf7d381a2e4702cb0ed99b3 Mon Sep 17 00:00:00 2001 From: useon Date: Sat, 3 Aug 2024 23:01:26 +0900 Subject: [PATCH 0508/1013] =?UTF-8?q?refactor:=20api=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=A5=B8=20roomId=EB=A5=BC=20=EC=9D=B8?= =?UTF-8?q?=EC=9E=90=EB=A1=9C=20=EB=84=98=EA=B2=A8=EC=A3=BC=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/NextRoundButton/NextRoundButton.hook.ts | 4 ++-- .../components/common/NextRoundButton/NextRoundButton.tsx | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/common/NextRoundButton/NextRoundButton.hook.ts b/frontend/src/components/common/NextRoundButton/NextRoundButton.hook.ts index 9857980a..8ececa7a 100644 --- a/frontend/src/components/common/NextRoundButton/NextRoundButton.hook.ts +++ b/frontend/src/components/common/NextRoundButton/NextRoundButton.hook.ts @@ -3,11 +3,11 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { moveNextRound } from '@/apis/balanceContent'; import { QUERY_KEYS } from '@/constants/queryKeys'; -const useMoveNextRoundMutation = () => { +const useMoveNextRoundMutation = (roomId: number) => { const queryClient = useQueryClient(); return useMutation({ - mutationFn: async () => await moveNextRound(), + mutationFn: async () => await moveNextRound(roomId), onSuccess: () => { queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.balanceContent] }); }, diff --git a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx index 2fb0498e..c3c2d79e 100644 --- a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx +++ b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx @@ -1,4 +1,4 @@ -import { useNavigate } from 'react-router-dom'; +import { useLocation, useNavigate } from 'react-router-dom'; import { useRecoilValue } from 'recoil'; import { useMoveNextRoundMutation } from './NextRoundButton.hook'; @@ -9,9 +9,11 @@ import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; import { memberInfoState } from '@/recoil/atom'; const NextRoundButton = () => { + const { search } = useLocation(); + const roomId = Number(new URLSearchParams(search).get('roomId')); const navigate = useNavigate(); const { balanceContent } = useBalanceContentQuery(); - const { mutateAsync: moveNextRound } = useMoveNextRoundMutation(); + const { mutateAsync: moveNextRound } = useMoveNextRoundMutation(roomId); const memberInfo = useRecoilValue(memberInfoState); const isLastRound = balanceContent?.currentRound === balanceContent?.totalRound; From e496ff56850da4bee013cbaadb759dcc2772f28a Mon Sep 17 00:00:00 2001 From: useon Date: Sat, 3 Aug 2024 23:02:54 +0900 Subject: [PATCH 0509/1013] =?UTF-8?q?refactor:=20=EB=9D=BC=EC=9A=B0?= =?UTF-8?q?=ED=8A=B8=20=EC=83=81=EC=88=98=ED=99=94=20=EC=A0=81=EC=9A=A9=20?= =?UTF-8?q?#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/common/NextRoundButton/NextRoundButton.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx index c3c2d79e..3623f8e7 100644 --- a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx +++ b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx @@ -5,6 +5,7 @@ import { useMoveNextRoundMutation } from './NextRoundButton.hook'; import Button from '../Button/Button'; import { bottomButtonLayout } from '../Button/Button.styled'; +import { ROUTES } from '@/constants/routes'; import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; import { memberInfoState } from '@/recoil/atom'; @@ -20,12 +21,12 @@ const NextRoundButton = () => { const isButtonDisabled = !memberInfo.isMaster; const goToGameResult = () => { - navigate('/game/result'); + navigate(ROUTES.gameResult); }; const goToNextRound = async () => { await moveNextRound(); - navigate('/game'); + navigate(ROUTES.game); }; return ( From dba4e7406619f51fa40f916dfc56ea848deff6a8 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Sat, 3 Aug 2024 23:09:10 +0900 Subject: [PATCH 0510/1013] =?UTF-8?q?refactor:=20=EB=B3=80=EC=88=98?= =?UTF-8?q?=EB=AA=85=20=EC=88=98=EC=A0=95=20#58?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../balance/vote/BalanceVoteServiceTest.java | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java index 01fe23f2..bb83a8c4 100644 --- a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java @@ -163,9 +163,9 @@ class 투표_종료_여부_조회 { private static final LocalDateTime ROUND_ENDED_AT = LocalDateTime.parse("2024-08-03T11:00:10"); private static final boolean IS_USED = false; - private Room myRoom; + private Room room; - private BalanceContent aVsB; + private BalanceContent balanceContent; private BalanceOption optionA; @@ -181,29 +181,29 @@ class 투표_종료_여부_조회 { @BeforeEach void setUp() { - aVsB = balanceContentRepository.save(new BalanceContent(Category.EXAMPLE, "A vs B")); - optionA = balanceOptionRepository.save(new BalanceOption("A", aVsB)); - optionB = balanceOptionRepository.save(new BalanceOption("B", aVsB)); - - myRoom = roomRepository.save(Room.createNewRoom()); - prin = memberRepository.save(PRIN.master(myRoom)); - tacan = memberRepository.save(TACAN.common(myRoom)); - keochan = memberRepository.save(KEOCHAN.common(myRoom)); - eden = memberRepository.save(EDEN.common(myRoom)); + balanceContent = balanceContentRepository.save(new BalanceContent(Category.EXAMPLE, "A vs B")); + optionA = balanceOptionRepository.save(new BalanceOption("A", balanceContent)); + optionB = balanceOptionRepository.save(new BalanceOption("B", balanceContent)); + + room = roomRepository.save(Room.createNewRoom()); + prin = memberRepository.save(PRIN.master(room)); + tacan = memberRepository.save(TACAN.common(room)); + keochan = memberRepository.save(KEOCHAN.common(room)); + eden = memberRepository.save(EDEN.common(room)); } @Test void 방의_모든_멤버가_컨텐츠에_투표하면_모두_투표한_것이다() { // given - int roomContentRound = 1; - roomContentRepository.save(new RoomContent(myRoom, aVsB, roomContentRound, ROUND_ENDED_AT, IS_USED)); + int round = 1; + roomContentRepository.save(new RoomContent(room, balanceContent, round, ROUND_ENDED_AT, IS_USED)); balanceVoteRepository.save(new BalanceVote(optionA, prin)); balanceVoteRepository.save(new BalanceVote(optionA, tacan)); balanceVoteRepository.save(new BalanceVote(optionB, keochan)); balanceVoteRepository.save(new BalanceVote(optionB, eden)); // when - VoteFinishedResponse actual = balanceVoteService.getAllVoteFinished(myRoom.getId(), aVsB.getId()); + VoteFinishedResponse actual = balanceVoteService.getAllVoteFinished(room.getId(), balanceContent.getId()); // then assertThat(actual.isFinished()).isTrue(); @@ -215,10 +215,10 @@ void setUp() { // given int roomContentRound = 1; LocalDateTime roundEndedAt = LocalDateTime.parse("2024-08-03T11:00:20"); - roomContentRepository.save(new RoomContent(myRoom, aVsB, roomContentRound, roundEndedAt, IS_USED)); + roomContentRepository.save(new RoomContent(room, balanceContent, roomContentRound, roundEndedAt, IS_USED)); // when - VoteFinishedResponse actual = balanceVoteService.getAllVoteFinished(myRoom.getId(), aVsB.getId()); + VoteFinishedResponse actual = balanceVoteService.getAllVoteFinished(room.getId(), balanceContent.getId()); // then assertThat(actual.isFinished()).isTrue(); @@ -227,14 +227,14 @@ void setUp() { @Test void 투표_제한_시간이_끝나지_않고_방의_모든_멤버가_투표하지_않았으면_모두_투표하지_않은_것이다() { // given - int roomContentRound = 1; - roomContentRepository.save(new RoomContent(myRoom, aVsB, roomContentRound, ROUND_ENDED_AT, IS_USED)); + int round = 1; + roomContentRepository.save(new RoomContent(room, balanceContent, round, ROUND_ENDED_AT, IS_USED)); balanceVoteRepository.save(new BalanceVote(optionA, prin)); balanceVoteRepository.save(new BalanceVote(optionA, tacan)); balanceVoteRepository.save(new BalanceVote(optionB, eden)); // when - VoteFinishedResponse actual = balanceVoteService.getAllVoteFinished(myRoom.getId(), aVsB.getId()); + VoteFinishedResponse actual = balanceVoteService.getAllVoteFinished(room.getId(), balanceContent.getId()); // then assertThat(actual.isFinished()).isFalse(); @@ -243,7 +243,7 @@ void setUp() { @Test void 방에_존재하지_않은_방_컨텐츠의_투표_여부를_조회하면_예외가_발생한다() { // when & then - assertThatThrownBy(() -> balanceVoteService.getAllVoteFinished(myRoom.getId(), aVsB.getId())) + assertThatThrownBy(() -> balanceVoteService.getAllVoteFinished(room.getId(), balanceContent.getId())) .isExactlyInstanceOf(BadRequestException.class) .hasMessageContaining("방에 존재하지 않은 컨텐츠입니다."); } @@ -251,11 +251,11 @@ void setUp() { @Test void 방의_현재_라운드와_다른_방_컨텐츠의_투표_여부를_조회하면_예외가_발생한다() { // given - int roomContentRound = 2; - roomContentRepository.save(new RoomContent(myRoom, aVsB, roomContentRound, ROUND_ENDED_AT, IS_USED)); + int round = 2; + roomContentRepository.save(new RoomContent(room, balanceContent, round, ROUND_ENDED_AT, IS_USED)); // when & then - assertThatThrownBy(() -> balanceVoteService.getAllVoteFinished(myRoom.getId(), aVsB.getId())) + assertThatThrownBy(() -> balanceVoteService.getAllVoteFinished(room.getId(), balanceContent.getId())) .isExactlyInstanceOf(BadRequestException.class) .hasMessageContaining("컨텐츠의 라운드가 일치하지 않습니다. 방 컨텐츠의 라운드 : 2, 요청한 라운드 : 1"); } @@ -263,12 +263,12 @@ void setUp() { @Test void 이미_사용된_방_컨텐츠의_투표_여부를_조회하면_예외가_발생한다() { // given - int roomContentRound = 1; + int round = 1; boolean isUsed = true; - roomContentRepository.save(new RoomContent(myRoom, aVsB, roomContentRound, ROUND_ENDED_AT, isUsed)); + roomContentRepository.save(new RoomContent(room, balanceContent, round, ROUND_ENDED_AT, isUsed)); // when & then - assertThatThrownBy(() -> balanceVoteService.getAllVoteFinished(myRoom.getId(), aVsB.getId())) + assertThatThrownBy(() -> balanceVoteService.getAllVoteFinished(room.getId(), balanceContent.getId())) .isExactlyInstanceOf(BadRequestException.class) .hasMessageContaining("이미 사용된 컨텐츠입니다."); } From 8f59d8e9e8d67ad0ca2e94d3ac8b8229ff37e884 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Sun, 4 Aug 2024 00:19:20 +0900 Subject: [PATCH 0511/1013] =?UTF-8?q?refactor:=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=88=9C=EC=84=9C=20=EB=B3=80=EA=B2=BD=20#58?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/balance/room/RoomContent.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java index 98dd3736..6c0c6438 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java @@ -63,6 +63,19 @@ public boolean isNotSameContentId(Long contentId) { return !Objects.equals(getContentId(), contentId); } + public void validateAlreadyUsed() { + if (isUsed) { + throw new BadRequestException("이미 사용된 컨텐츠입니다."); + } + } + + public void validateSameRound(int round) { + if (this.round != round) { + throw new BadRequestException("컨텐츠의 라운드가 일치하지 않습니다. 방 컨텐츠의 라운드 : %d, 요청한 라운드 : %d" + .formatted(this.round, round)); + } + } + public Long getContentId() { return balanceContent.getId(); } @@ -85,17 +98,4 @@ public LocalDateTime getRoundEndedAt() { } return roundEndedAt; } - - public void validateAlreadyUsed() { - if (isUsed) { - throw new BadRequestException("이미 사용된 컨텐츠입니다."); - } - } - - public void validateSameRound(int round) { - if (this.round != round) { - throw new BadRequestException("컨텐츠의 라운드가 일치하지 않습니다. 방 컨텐츠의 라운드 : %d, 요청한 라운드 : %d" - .formatted(this.round, round)); - } - } } From ab2614042fc303118a497e8d2c11c2ec75af639a Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sun, 4 Aug 2024 00:47:59 +0900 Subject: [PATCH 0512/1013] =?UTF-8?q?refactor:=20CI=EB=A5=BC=20=EC=9C=84?= =?UTF-8?q?=ED=95=B4=20=EC=9E=91=EC=84=B1=ED=95=9C=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=A0=9C=EA=B1=B0=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/tests/sum.test.ts | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 frontend/src/tests/sum.test.ts diff --git a/frontend/src/tests/sum.test.ts b/frontend/src/tests/sum.test.ts deleted file mode 100644 index 7c40f811..00000000 --- a/frontend/src/tests/sum.test.ts +++ /dev/null @@ -1,7 +0,0 @@ -// Test Example - -const sum = (a: number, b: number) => a + b; - -test('adds 1 + 2 to equal 3', () => { - expect(sum(1, 2)).toBe(3); -}); From 4bfc36069ba2b745d1a97c8e7fcd72a102dcb587 Mon Sep 17 00:00:00 2001 From: useon Date: Sun, 4 Aug 2024 02:14:21 +0900 Subject: [PATCH 0513/1013] =?UTF-8?q?refactor:=20=EB=8B=A4=EC=9D=8C=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B4=EB=93=9C=EB=A1=9C=20=EB=84=98=EC=96=B4?= =?UTF-8?q?=EA=B0=80=EA=B8=B0=20api=20=EB=B3=80=EA=B2=BD=EC=97=90=20?= =?UTF-8?q?=EB=94=B0=EB=9D=BC=20=EC=88=98=EC=A0=95=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/balanceContent.ts | 6 +----- frontend/src/constants/url.ts | 2 +- frontend/src/mocks/handlers/voteHandler.ts | 5 ++--- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/frontend/src/apis/balanceContent.ts b/frontend/src/apis/balanceContent.ts index 4090de87..c43feb5d 100644 --- a/frontend/src/apis/balanceContent.ts +++ b/frontend/src/apis/balanceContent.ts @@ -76,17 +76,13 @@ export const checkMyGameStatus = async ({ }; // 다음 라운드로 이동하기 -export const moveNextRound = async (roomId: number): Promise => { +export const moveNextRound = async (roomId: number) => { const res = await fetcher.patch({ url: API_URL.moveNextRound(roomId), headers: { 'Content-Type': `application/json`, }, }); - - const data = await res.json(); - - return data; }; // 최종 결과 가져오기 diff --git a/frontend/src/constants/url.ts b/frontend/src/constants/url.ts index c9e8a0e3..c4ac5464 100644 --- a/frontend/src/constants/url.ts +++ b/frontend/src/constants/url.ts @@ -17,6 +17,6 @@ export const MOCK_API_URL = { vote: '/api/balances/rooms/:roomId/contents/:contentId/votes', roundVoteResult: '/api/balances/rooms/:roomId/contents/:contentId/vote-result', myGameStatus: '/api/balances/rooms/:roomId?myRound=:myRound', - moveNextRound: '/api/balances/rooms/:roomId/contents', + moveNextRound: '/api/balances/rooms/:roomId/next-round', finalResult: '/api/balances/rooms/:roomId/final', }; diff --git a/frontend/src/mocks/handlers/voteHandler.ts b/frontend/src/mocks/handlers/voteHandler.ts index c3f94383..1cff15c7 100644 --- a/frontend/src/mocks/handlers/voteHandler.ts +++ b/frontend/src/mocks/handlers/voteHandler.ts @@ -26,8 +26,7 @@ const fetchVoteResultHandler = async () => { const goToNextRoundHandler = () => { BALANCE_CONTENT.currentRound += 1; - - return HttpResponse.json(BALANCE_CONTENT, { status: 201 }); + return HttpResponse.json({ state: 204 }); }; const fetchFinalResultHandler = async () => { @@ -46,6 +45,6 @@ export const voteHandler = [ http.post(MOCK_API_URL.vote, voteBalanceContentHandler), http.get(MOCK_API_URL.roundVoteResult, fetchVoteResultHandler), http.get(MOCK_API_URL.myGameStatus, checkMyGameStatusHandler), - http.post(MOCK_API_URL.moveNextRound, goToNextRoundHandler), + http.patch(MOCK_API_URL.moveNextRound, goToNextRoundHandler), http.get(MOCK_API_URL.finalResult, fetchFinalResultHandler), ]; From d97ca92e89202519a2a3b63941ac644418ddbc4b Mon Sep 17 00:00:00 2001 From: useon Date: Sun, 4 Aug 2024 02:16:40 +0900 Subject: [PATCH 0514/1013] =?UTF-8?q?test:=20=EB=B0=A9=EC=9E=A5=EC=9D=B4?= =?UTF-8?q?=20=EB=8B=A4=EC=9D=8C=20=EB=9D=BC=EC=9A=B4=EB=93=9C=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=EC=9D=84=20=EB=88=84=EB=A5=B4=EB=A9=B4=20=EB=8B=A4?= =?UTF-8?q?=EC=9D=8C=20=EB=9D=BC=EC=9A=B4=EB=93=9C=EB=A1=9C=20=EB=84=98?= =?UTF-8?q?=EC=96=B4=EA=B0=80=EB=8A=94=20msw=20=EA=B5=AC=ED=98=84=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/mocks/handlers/voteHandler.ts | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/frontend/src/mocks/handlers/voteHandler.ts b/frontend/src/mocks/handlers/voteHandler.ts index 1cff15c7..e6bd4dc4 100644 --- a/frontend/src/mocks/handlers/voteHandler.ts +++ b/frontend/src/mocks/handlers/voteHandler.ts @@ -6,7 +6,6 @@ import MY_GAME_STATUS from '../data/myGameStatus.json'; import VOTE_RESULT from '../data/roundVoteResult.json'; import { MOCK_API_URL } from '@/constants/url'; -import { BalanceContent } from '@/types/balanceContent'; import { RoundVoteResult } from '@/types/roundVoteResult'; const voteBalanceContentHandler = async ({ request }: { request: Request }) => { @@ -26,6 +25,7 @@ const fetchVoteResultHandler = async () => { const goToNextRoundHandler = () => { BALANCE_CONTENT.currentRound += 1; + MY_GAME_STATUS.isRoundFinished = true; return HttpResponse.json({ state: 204 }); }; @@ -33,18 +33,9 @@ const fetchFinalResultHandler = async () => { return HttpResponse.json(FINAL_RESULT); }; -const checkMyGameStatusHandler = () => { - setTimeout(() => { - MY_GAME_STATUS.isRoundFinished = true; - }, 5 * 1000); - - return HttpResponse.json(MY_GAME_STATUS); -}; - export const voteHandler = [ http.post(MOCK_API_URL.vote, voteBalanceContentHandler), http.get(MOCK_API_URL.roundVoteResult, fetchVoteResultHandler), - http.get(MOCK_API_URL.myGameStatus, checkMyGameStatusHandler), http.patch(MOCK_API_URL.moveNextRound, goToNextRoundHandler), http.get(MOCK_API_URL.finalResult, fetchFinalResultHandler), ]; From 70a0cc2415550cedd73cf404cd1b267fc485a0b3 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Sun, 4 Aug 2024 02:41:21 +0900 Subject: [PATCH 0515/1013] =?UTF-8?q?refactor:=20code=20review=20=EB=B0=98?= =?UTF-8?q?=EC=98=81=20#92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/room.ts | 6 ++-- .../CategoryContainer.styled.ts | 3 +- .../ReadyMembersContainer.tsx | 6 ++-- .../components/common/Modal/Modal.styled.ts | 1 - .../src/components/layout/Header/Header.tsx | 11 ++++++++ .../pages/NicknamePage/useMakeOrEnterRoom.ts | 28 ++++++++++--------- frontend/src/types/room.ts | 2 +- 7 files changed, 35 insertions(+), 22 deletions(-) diff --git a/frontend/src/apis/room.ts b/frontend/src/apis/room.ts index f14eff73..bd6b2edd 100644 --- a/frontend/src/apis/room.ts +++ b/frontend/src/apis/room.ts @@ -1,10 +1,10 @@ import fetcher from './fetcher'; import { API_URL } from '@/constants/url'; -import { RoomInfo, RoomMembers, RoomAndMember } from '@/types/room'; +import { RoomInfo, RoomIdAndMember } from '@/types/room'; // 방 만들기 -export const makeRoom = async (nickname: string): Promise => { +export const createRoom = async (nickname: string): Promise => { const res = await fetcher.post({ url: API_URL.room, headers: { @@ -25,7 +25,7 @@ export const makeRoom = async (nickname: string): Promise => { }; // 방 참여하기 -export const enterRoom = async (roomId: number, nickname: string): Promise => { +export const enterRoom = async (roomId: number, nickname: string): Promise => { const res = await fetcher.post({ url: API_URL.enterRoom(roomId), headers: { diff --git a/frontend/src/components/CategoryContainer/CategoryContainer.styled.ts b/frontend/src/components/CategoryContainer/CategoryContainer.styled.ts index 22bf4171..a53ae120 100644 --- a/frontend/src/components/CategoryContainer/CategoryContainer.styled.ts +++ b/frontend/src/components/CategoryContainer/CategoryContainer.styled.ts @@ -1,6 +1,7 @@ import { css } from '@emotion/react'; import { Theme } from '@/styles/Theme'; +import getBorderRadius from '@/styles/utils/getBorderRadius'; export const categoryContainerLayout = css` display: flex; @@ -9,7 +10,7 @@ export const categoryContainerLayout = css` align-items: center; height: 10rem; padding: 1.6rem 0 2.4rem; - border-radius: 2rem; + border-radius: ${getBorderRadius('medium')}; background-color: ${Theme.color.peanut400}; `; diff --git a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx index 20d327e4..fb379cb1 100644 --- a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx +++ b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx @@ -17,13 +17,13 @@ interface ReadyMembersContainerProps extends RoomMembers {} const ReadyMembersContainer = ({ members }: ReadyMembersContainerProps) => { return (
    -
    총 인원 {members.length}명
    +

    총 인원 {members.length}명

    • -
      +
      +
      초대하기
    • {members.map((member) => ( diff --git a/frontend/src/components/common/Modal/Modal.styled.ts b/frontend/src/components/common/Modal/Modal.styled.ts index 1797eac3..3d981583 100644 --- a/frontend/src/components/common/Modal/Modal.styled.ts +++ b/frontend/src/components/common/Modal/Modal.styled.ts @@ -113,7 +113,6 @@ export const modalTextButton = ({ height: ${buttonHeight}; padding: 1rem; border: none; - border-radius: 0; border-radius: 0.8rem; background-color: ${backgroundColor}; diff --git a/frontend/src/components/layout/Header/Header.tsx b/frontend/src/components/layout/Header/Header.tsx index 599c81c2..45bd5f48 100644 --- a/frontend/src/components/layout/Header/Header.tsx +++ b/frontend/src/components/layout/Header/Header.tsx @@ -19,6 +19,7 @@ const Header = ({ title }: HeaderProps) => { const isRoundResultPage = location.pathname === ROUTES.roundResult; const isFinalPage = location.pathname === ROUTES.gameResult; + const isNicknamePage = location.pathname.startsWith(ROUTES.nickname); if (isFinalPage) { return
      ; @@ -34,6 +35,16 @@ const Header = ({ title }: HeaderProps) => { ); } + if (isNicknamePage) { + return ( +
      + + 닉네임 설정 + +
      + ); + } + return (
      diff --git a/frontend/src/pages/NicknamePage/useMakeOrEnterRoom.ts b/frontend/src/pages/NicknamePage/useMakeOrEnterRoom.ts index f518750a..c56862a9 100644 --- a/frontend/src/pages/NicknamePage/useMakeOrEnterRoom.ts +++ b/frontend/src/pages/NicknamePage/useMakeOrEnterRoom.ts @@ -3,9 +3,9 @@ import { useRef } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import { useRecoilValue } from 'recoil'; -import { enterRoom, makeRoom } from '@/apis/room'; +import { enterRoom, createRoom } from '@/apis/room'; import { memberInfoState } from '@/recoil/atom'; -import { RoomAndMember } from '@/types/room'; +import { RoomIdAndMember } from '@/types/room'; import { createRandomNickname } from '@/utils/nickname'; export const useMakeOrEnterRoom = () => { @@ -16,27 +16,29 @@ export const useMakeOrEnterRoom = () => { const { roomId } = useParams(); const nickname = nicknameInputRef.current?.value || randomNickname; - const makeRoomMutation = useMutation({ - mutationFn: makeRoom, + const createRoomMutation = useMutation({ + mutationFn: createRoom, onSuccess: (data) => { navigate(`/ready/${data.roomId}`); }, onError: (error: Error) => {}, }); - const enterRoomMutation = useMutation( - { - mutationFn: ({ nickname, roomId }) => enterRoom(roomId, nickname), - onSuccess: () => { - navigate(`/ready/${roomId}`); - }, - onError: (error: Error) => {}, + const enterRoomMutation = useMutation< + RoomIdAndMember, + Error, + { nickname: string; roomId: number } + >({ + mutationFn: ({ nickname, roomId }) => enterRoom(roomId, nickname), + onSuccess: () => { + navigate(`/ready/${roomId}`); }, - ); + onError: (error: Error) => {}, + }); const handleMakeOrEnterRoom = () => { if (isMaster) { - makeRoomMutation.mutate(nickname); + createRoomMutation.mutate(nickname); } else { enterRoomMutation.mutate({ nickname, roomId: Number(roomId) }); } diff --git a/frontend/src/types/room.ts b/frontend/src/types/room.ts index 0ff066b4..8cbe2188 100644 --- a/frontend/src/types/room.ts +++ b/frontend/src/types/room.ts @@ -19,7 +19,7 @@ export interface RoomMembers { members: Member[]; } -export interface RoomAndMember { +export interface RoomIdAndMember { roomId: number; member: Member; } From a32a631bcb518211d2e0952119e6e517357362e9 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Sun, 4 Aug 2024 03:30:33 +0900 Subject: [PATCH 0516/1013] =?UTF-8?q?refactor:=20-P=20=EC=98=B5=EC=85=98?= =?UTF-8?q?=EC=9D=84=20=EC=82=AC=EC=9A=A9=ED=95=A0=20=EB=95=8C=20RestDocs?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20task=EA=B0=80=20=EC=8B=A4=ED=96=89?= =?UTF-8?q?=EB=90=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20#118?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 +- backend/build.gradle | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index fc80a9bd..4e90c242 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -37,7 +37,7 @@ jobs: run: chmod +x gradlew - name: Build with Gradle - run: ./gradlew bootJar + run: ./gradlew bootJar -PcreateRestDocs - name: Log in to Docker Hub uses: docker/login-action@v3 diff --git a/backend/build.gradle b/backend/build.gradle index 6640785d..302e6a58 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -53,15 +53,21 @@ tasks.named('jar') { enabled = false } -tasks.named('test') { +tasks.withType(Test).configureEach { useJUnitPlatform() reports.html.required = false reports.junitXml.required = false +} + +tasks.register('restDocsTest', Test) { outputs.dir snippetsDir + filter { + includeTestsMatching 'ddangkong.documentation.*' + } } tasks.named('asciidoctor') { - dependsOn test + dependsOn restDocsTest inputs.dir snippetsDir configurations 'asciidoctorExt' sources { @@ -71,8 +77,10 @@ tasks.named('asciidoctor') { } tasks.named('bootJar') { - dependsOn asciidoctor - from("${asciidoctor.outputDir}") { - into 'static/docs' + if (project.hasProperty('createRestDocs')) { + dependsOn asciidoctor + from("${asciidoctor.outputDir}") { + into 'static/docs' + } } } From 4615b24ce6a2c8c09c2cdce4c01d93fdc898764c Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Sun, 4 Aug 2024 03:59:57 +0900 Subject: [PATCH 0517/1013] =?UTF-8?q?refactor:=20CI=EC=97=90=EC=84=9C=20te?= =?UTF-8?q?st=20task=20=EC=8B=A4=ED=96=89=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20#118?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-ci-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/be-ci-dev.yml b/.github/workflows/be-ci-dev.yml index bbc9ab08..57b6be73 100644 --- a/.github/workflows/be-ci-dev.yml +++ b/.github/workflows/be-ci-dev.yml @@ -31,4 +31,4 @@ jobs: run: chmod +x gradlew - name: Build with Gradle - run: ./gradlew build + run: ./gradlew test From de696c51667351c48be5742f6ae57d31b058f742 Mon Sep 17 00:00:00 2001 From: jhon3242 Date: Sun, 4 Aug 2024 13:47:07 +0900 Subject: [PATCH 0518/1013] =?UTF-8?q?feat:=20isUsed=20=ED=95=84=EB=93=9C?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=20#113?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ddangkong/domain/balance/room/RoomContent.java | 3 +++ .../domain/balance/room/RoomContentRepository.java | 2 ++ .../service/balance/content/BalanceContentService.java | 2 +- backend/src/test/resources/init-test.sql | 10 +++++----- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java index 22ab7f88..bb0c3fbe 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java @@ -35,6 +35,9 @@ public class RoomContent extends BaseEntity { @Column(nullable = false) private int round; + @Column(nullable = false) + private boolean isUsed; + public Long getContentId() { return balanceContent.getId(); } diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomContentRepository.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomContentRepository.java index dd0b3f38..ed783d89 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomContentRepository.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomContentRepository.java @@ -6,4 +6,6 @@ public interface RoomContentRepository extends JpaRepository { Optional findByRoomAndRound(Room room, int round); + + Optional findByRoomAndRoundAndIsUsed(Room room, int round, boolean isUsed); } diff --git a/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java b/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java index cce442a9..2bfa772e 100644 --- a/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java +++ b/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java @@ -44,7 +44,7 @@ private Room findProgessingRoom(Long roomId) { } private RoomContent findCurrentRoomContent(Room room) { - return roomContentRepository.findByRoomAndRound(room, room.getCurrentRound()) + return roomContentRepository.findByRoomAndRoundAndIsUsed(room, room.getCurrentRound(), false) .orElseThrow(() -> new BadRequestException("해당 방의 현재 진행중인 질문이 존재하지 않습니다.")); } } diff --git a/backend/src/test/resources/init-test.sql b/backend/src/test/resources/init-test.sql index c806f710..3d7b21bc 100644 --- a/backend/src/test/resources/init-test.sql +++ b/backend/src/test/resources/init-test.sql @@ -20,11 +20,11 @@ VALUES ('EXAMPLE', '민초 vs 반민초'), ('EXAMPLE', '월 200 백수 vs 월 500 직장인'), ('EXAMPLE', '다음 중 여행가고 싶은 곳은?'); -INSERT INTO room_content (room_id, balance_content_id, round, created_at) -VALUES (1, 2, 1, '2024-07-18 19:50:00.000'), - (1, 1, 2, '2024-07-18 20:00:00.000'), - (1, 3, 3, '2024-07-18 20:00:00.000'), - (3, 1, 1, '2024-07-18 19:51:00.000'); +INSERT INTO room_content (room_id, balance_content_id, round, created_at, is_used) +VALUES (1, 2, 1, '2024-07-18 19:50:00.000', false), + (1, 1, 2, '2024-07-18 20:00:00.000', false), + (1, 3, 3, '2024-07-18 20:00:00.000', false), + (3, 1, 1, '2024-07-18 19:51:00.000', false); INSERT INTO balance_option (name, balance_content_id) VALUES ('민초', 1), From 8c8c643fc7780c77457624827688b35bc37dc5a9 Mon Sep 17 00:00:00 2001 From: jhon3242 Date: Sun, 4 Aug 2024 13:51:50 +0900 Subject: [PATCH 0519/1013] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=EC=BC=80=EC=9D=B4=EC=8A=A4=EB=A5=BC=20=EB=B6=84=EB=A6=AC=20?= =?UTF-8?q?#113?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/BalanceContentServiceTest.java | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java index f9178036..a3c4139e 100644 --- a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java @@ -62,16 +62,19 @@ class 현재_방의_밸런스_게임_내용_조회 { } @Test - void 방의_상태가_진행중이_아닌_경우_예외를_던진다() { + void 방의_준비_상태인_경우_예외를_던진다() { // when & then - assertAll( - () -> assertThatThrownBy(() -> balanceContentService.findRecentBalanceContent(READY_ROOM_ID)) - .isInstanceOf(BadRequestException.class) - .hasMessage("해당 방은 게임을 진행하고 있지 않습니다."), - () -> assertThatThrownBy(() -> balanceContentService.findRecentBalanceContent(FINISHED_ROOM_ID)) - .isInstanceOf(BadRequestException.class) - .hasMessage("해당 방은 게임을 진행하고 있지 않습니다.") - ); + assertThatThrownBy(() -> balanceContentService.findRecentBalanceContent(READY_ROOM_ID)) + .isInstanceOf(BadRequestException.class) + .hasMessage("해당 방은 게임을 진행하고 있지 않습니다."); + } + + @Test + void 방이_종료_상태인_경우_예외를_던진다() { + // when & then + assertThatThrownBy(() -> balanceContentService.findRecentBalanceContent(FINISHED_ROOM_ID)) + .isInstanceOf(BadRequestException.class) + .hasMessage("해당 방은 게임을 진행하고 있지 않습니다."); } } } From 52fa344fa2fa33dac922b45bc7918b50cf7890cb Mon Sep 17 00:00:00 2001 From: useon Date: Sun, 4 Aug 2024 14:08:08 +0900 Subject: [PATCH 0520/1013] =?UTF-8?q?feat:=20=EC=9C=A0=EC=A0=80=EC=9D=98?= =?UTF-8?q?=20=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EA=B4=80=EB=A6=AC=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EC=A0=84=EC=97=AD=20=EC=83=81=ED=83=9C=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=20=EC=83=9D=EC=84=B1=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/recoil/atom.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 frontend/src/recoil/atom.ts diff --git a/frontend/src/recoil/atom.ts b/frontend/src/recoil/atom.ts new file mode 100644 index 00000000..3984ea6b --- /dev/null +++ b/frontend/src/recoil/atom.ts @@ -0,0 +1,10 @@ +import { atom } from 'recoil'; + +export const memberInfoState = atom({ + key: 'memberInfo', + default: { + memberId: null, + nickname: null, + isMaster: false, + }, +}); From d21144a839538a20912d766528acf9722709b348 Mon Sep 17 00:00:00 2001 From: useon Date: Sun, 4 Aug 2024 14:12:34 +0900 Subject: [PATCH 0521/1013] =?UTF-8?q?refactor:=20=EC=9D=B4=EB=AF=B8=20defa?= =?UTF-8?q?ult=20true=EA=B0=92=EC=9C=BC=EB=A1=9C=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=EB=90=98=EC=96=B4=20=EC=9E=88=EB=8A=94=20refetchOnWindowFocus?= =?UTF-8?q?=20=EC=BD=94=EB=93=9C=20=EC=82=AD=EC=A0=9C=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useMyGameStatusQuery.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/hooks/useMyGameStatusQuery.ts b/frontend/src/hooks/useMyGameStatusQuery.ts index 9e27e2e8..b4c16acc 100644 --- a/frontend/src/hooks/useMyGameStatusQuery.ts +++ b/frontend/src/hooks/useMyGameStatusQuery.ts @@ -24,7 +24,6 @@ const useMyGameStatusQuery = ({ roomId, balanceContent }: useMyGameStatusQueryPr enabled: !!balanceContent, staleTime: 0, refetchInterval: 1000, - refetchOnWindowFocus: true, }); return { From a24bab935505977db3f1d43b3eb4d5e1da3ed09d Mon Sep 17 00:00:00 2001 From: useon Date: Sun, 4 Aug 2024 14:25:48 +0900 Subject: [PATCH 0522/1013] =?UTF-8?q?feat:=20=EB=8B=A4=EC=9D=8C=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B4=EB=93=9C=20=EB=98=90=EB=8A=94=20=EB=8C=80?= =?UTF-8?q?=EA=B8=B0=EC=8B=A4=EB=A1=9C=20=EC=9D=B4=EB=8F=99=EC=8B=9C=20?= =?UTF-8?q?=EB=92=A4=EB=A1=9C=20=EA=B0=80=EA=B8=B0=EA=B0=80=20=EC=95=88=20?= =?UTF-8?q?=EB=90=98=EB=8F=84=EB=A1=9D=20=ED=95=98=EB=8A=94=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/common/NextRoundButton/NextRoundButton.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx index 3623f8e7..00fb0f94 100644 --- a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx +++ b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx @@ -21,12 +21,12 @@ const NextRoundButton = () => { const isButtonDisabled = !memberInfo.isMaster; const goToGameResult = () => { - navigate(ROUTES.gameResult); + navigate(ROUTES.gameResult, { replace: true }); }; const goToNextRound = async () => { await moveNextRound(); - navigate(ROUTES.game); + navigate(ROUTES.game, { replace: true }); }; return ( From 35009744604ac04677d2e807df84aec23554a468 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sun, 4 Aug 2024 14:34:50 +0900 Subject: [PATCH 0523/1013] =?UTF-8?q?chore:=20GA4(google=20analytics=204)?= =?UTF-8?q?=20=EC=97=B0=EA=B2=B0=20#129?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/index.html | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/frontend/index.html b/frontend/index.html index 805a6cfa..1024288a 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1,11 +1,21 @@ - - - - ddangkong - - - -
      - + + + + + ddangkong + + + + + +
      + + From 2a8cd634186f6265b576a65430295758494208a4 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Sun, 4 Aug 2024 13:44:15 +0900 Subject: [PATCH 0524/1013] =?UTF-8?q?refactor:=20FixedClock=20=EB=AA=85?= =?UTF-8?q?=EC=8B=9C=20=EB=B0=8F=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=88=98=EC=A0=95=20#58?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/balance/vote/BalanceVoteServiceTest.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java index bb83a8c4..316490bd 100644 --- a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java @@ -193,10 +193,12 @@ void setUp() { } @Test - void 방의_모든_멤버가_컨텐츠에_투표하면_모두_투표한_것이다() { + @FixedClock(date = "2024-08-03", time = "11:00:19") + void 투표_제한_시간이_끝나지_않았지만_방의_모든_멤버가_컨텐츠에_투표했으면_모두_투표한_것이다() { // given int round = 1; - roomContentRepository.save(new RoomContent(room, balanceContent, round, ROUND_ENDED_AT, IS_USED)); + LocalDateTime roundEndedAt = LocalDateTime.parse("2024-08-03T11:00:20"); + roomContentRepository.save(new RoomContent(room, balanceContent, round, roundEndedAt, IS_USED)); balanceVoteRepository.save(new BalanceVote(optionA, prin)); balanceVoteRepository.save(new BalanceVote(optionA, tacan)); balanceVoteRepository.save(new BalanceVote(optionB, keochan)); @@ -211,7 +213,7 @@ void setUp() { @Test @FixedClock(date = "2024-08-03", time = "11:00:21") - void 컨텐츠의_투표_제한_시간이_지나면_모두_투표한_것이다() { + void 방의_모든_멤버가_투표하지_않았지만_컨텐츠의_투표_제한_시간이_지나면_모두_투표한_것이다() { // given int roomContentRound = 1; LocalDateTime roundEndedAt = LocalDateTime.parse("2024-08-03T11:00:20"); From 9eb4d526ab94deff59ae70d82743780f9a3e4700 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Sun, 4 Aug 2024 14:43:17 +0900 Subject: [PATCH 0525/1013] =?UTF-8?q?refactor:=20RoomContent=EC=9D=98=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B4=EB=93=9C=20=EC=A2=85=EB=A3=8C=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8=20=EA=B8=B0=EB=8A=A5=EC=9C=BC=EB=A1=9C=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EC=9D=B4=EB=8F=99=20=EB=B0=8F=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81=20#58?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../option/BalanceOptionRepository.java | 2 +- .../domain/balance/room/RoomContent.java | 21 +-- .../domain/member/MemberRepository.java | 2 +- .../balance/vote/BalanceVoteService.java | 39 ++--- .../domain/balance/room/RoomContentTest.java | 54 +++--- .../balance/vote/BalanceVoteServiceTest.java | 154 +++++++++--------- 6 files changed, 127 insertions(+), 145 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/option/BalanceOptionRepository.java b/backend/src/main/java/ddangkong/domain/balance/option/BalanceOptionRepository.java index 768406b4..c8d02fb5 100644 --- a/backend/src/main/java/ddangkong/domain/balance/option/BalanceOptionRepository.java +++ b/backend/src/main/java/ddangkong/domain/balance/option/BalanceOptionRepository.java @@ -10,7 +10,7 @@ public interface BalanceOptionRepository extends JpaRepository findAllByBalanceContent(BalanceContent balanceContent); - Optional findByIdAndBalanceContentId(Long id, Long contentId); + Optional findByIdAndBalanceContent(Long id, BalanceContent balanceContent); default BalanceOption getById(Long id) { return findById(id) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java index 6c0c6438..f80ada0c 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java @@ -13,7 +13,6 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import java.time.LocalDateTime; -import java.util.Objects; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -55,27 +54,25 @@ public RoomContent(Room room, this.isUsed = isUsed; } - public boolean isRoundOver(LocalDateTime currentTime) { + public boolean isRoundOver(LocalDateTime currentTime, int round) { + validateSameRound(round); + validateAlreadyUsed(); return currentTime.isAfter(getRoundEndedAt()); } - public boolean isNotSameContentId(Long contentId) { - return !Objects.equals(getContentId(), contentId); + private void validateSameRound(int round) { + if (this.round != round) { + throw new BadRequestException("컨텐츠의 라운드가 일치하지 않습니다. 방 컨텐츠의 라운드 : %d, 요청한 라운드 : %d" + .formatted(this.round, round)); + } } - public void validateAlreadyUsed() { + private void validateAlreadyUsed() { if (isUsed) { throw new BadRequestException("이미 사용된 컨텐츠입니다."); } } - public void validateSameRound(int round) { - if (this.round != round) { - throw new BadRequestException("컨텐츠의 라운드가 일치하지 않습니다. 방 컨텐츠의 라운드 : %d, 요청한 라운드 : %d" - .formatted(this.round, round)); - } - } - public Long getContentId() { return balanceContent.getId(); } diff --git a/backend/src/main/java/ddangkong/domain/member/MemberRepository.java b/backend/src/main/java/ddangkong/domain/member/MemberRepository.java index 86f988b6..0162723f 100644 --- a/backend/src/main/java/ddangkong/domain/member/MemberRepository.java +++ b/backend/src/main/java/ddangkong/domain/member/MemberRepository.java @@ -10,7 +10,7 @@ public interface MemberRepository extends JpaRepository { List findAllByRoom(Room room); - Optional findByIdAndRoomId(Long id, Long roomId); + Optional findByIdAndRoom(Long id, Room room); default Member getById(Long id) { return findById(id) diff --git a/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java b/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java index 1c5e3a47..0779d57e 100644 --- a/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java +++ b/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java @@ -48,35 +48,29 @@ public class BalanceVoteService { @Transactional public BalanceVoteResponse createBalanceVote(BalanceVoteRequest request, Long roomId, Long contentId) { - validateRoundEnded(roomId, contentId); - BalanceOption balanceOption = findValidOption(request.optionId(), contentId); - Member member = findValidMember(request.memberId(), roomId); + Room room = roomRepository.getById(roomId); + BalanceContent balanceContent = balanceContentRepository.getById(contentId); + validateRoundFinished(room, balanceContent); + BalanceOption balanceOption = getValidOption(request.optionId(), balanceContent); + Member member = getValidMember(request.memberId(), room); - BalanceVote balanceVote = new BalanceVote(balanceOption, member); - BalanceVote savedBalanceVote = balanceVoteRepository.save(balanceVote); - return new BalanceVoteResponse(savedBalanceVote); + BalanceVote balanceVote = balanceVoteRepository.save(new BalanceVote(balanceOption, member)); + return new BalanceVoteResponse(balanceVote); } - private void validateRoundEnded(Long roomId, Long contentId) { - RoomContent roomContent = findValidRoomContent(roomId); - if (roomContent.isNotSameContentId(contentId) || roomContent.isRoundOver(LocalDateTime.now(clock))) { - throw new BadRequestException("유효하지 않은 라운드에는 투표할 수 없습니다."); + private void validateRoundFinished(Room room, BalanceContent balanceContent) { + if (isRoundFinished(room, balanceContent)) { + throw new BadRequestException("이미 종료된 라운드에는 투표할 수 없습니다."); } } - private RoomContent findValidRoomContent(Long roomId) { - Room room = roomRepository.getById(roomId); - return roomContentRepository.findByRoomAndRound(room, room.getCurrentRound()) - .orElseThrow(() -> new BadRequestException("해당 방의 현재 진행중인 질문이 존재하지 않습니다.")); - } - - private BalanceOption findValidOption(Long optionId, Long contentId) { - return balanceOptionRepository.findByIdAndBalanceContentId(optionId, contentId) + private BalanceOption getValidOption(Long optionId, BalanceContent balanceContent) { + return balanceOptionRepository.findByIdAndBalanceContent(optionId, balanceContent) .orElseThrow(() -> new BadRequestException("해당 질문의 선택지가 존재하지 않습니다.")); } - private Member findValidMember(Long memberId, Long roomId) { - return memberRepository.findByIdAndRoomId(memberId, roomId) + private Member getValidMember(Long memberId, Room room) { + return memberRepository.findByIdAndRoom(memberId, room) .orElseThrow(() -> new BadRequestException("해당 방의 멤버가 존재하지 않습니다.")); } @@ -134,9 +128,8 @@ public VoteFinishedResponse getAllVoteFinished(Long roomId, Long contentId) { private boolean isRoundFinished(Room room, BalanceContent balanceContent) { RoomContent roomContent = roomContentRepository.getByRoomAndBalanceContent(room, balanceContent); - roomContent.validateSameRound(room.getCurrentRound()); - roomContent.validateAlreadyUsed(); - return roomContent.isRoundOver(LocalDateTime.now(clock)); + LocalDateTime now = LocalDateTime.now(clock); + return roomContent.isRoundOver(now, room.getCurrentRound()); } private boolean isAllVoteFinished(Room room, BalanceContent balanceContent) { diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java index b224bd03..43099357 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java @@ -1,6 +1,6 @@ package ddangkong.domain.balance.room; -import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import ddangkong.domain.balance.content.BalanceContent; @@ -16,61 +16,59 @@ class RoomContentTest { private static final BalanceContent BALANCE_CONTENT = new BalanceContent(Category.EXAMPLE, "치킨 vs 피자"); @Nested - class 컨텐츠_사용_여부 { + class 라운드_종료_여부 { private static final int ROUND = 1; private static final LocalDateTime ROUND_ENDED_AT = LocalDateTime.parse("2024-08-03T20:00:02"); + private static final boolean IS_USED = false; @Test - void 사용된_컨텐츠면_예외가_발생한다() { + void 라운드_종료_시간보다_이전_시간이면_라운드가_종료되지_않은_것이다() { // given - boolean isUsed = true; - RoomContent roomContent = new RoomContent(ROOM, BALANCE_CONTENT, ROUND, ROUND_ENDED_AT, isUsed); + LocalDateTime roundEndedAt = LocalDateTime.parse("2024-08-03T20:00:02"); + RoomContent roomContent = new RoomContent(ROOM, BALANCE_CONTENT, ROUND, roundEndedAt, IS_USED); + LocalDateTime now = LocalDateTime.parse("2024-08-03T20:00:01"); // when & then - assertThatThrownBy(roomContent::validateAlreadyUsed) - .isExactlyInstanceOf(BadRequestException.class) - .hasMessageContaining("이미 사용된 컨텐츠입니다."); + assertThat(roomContent.isRoundOver(now, ROUND)).isFalse(); } @Test - void 사용된_컨텐츠가_아니면_예외가_발생하지_않는다() { + void 라운드_종료_시간보다_이후_시간이면_라운드가_종료되지_않은_것이다() { // given - boolean isUsed = false; - RoomContent roomContent = new RoomContent(ROOM, BALANCE_CONTENT, ROUND, ROUND_ENDED_AT, isUsed); + LocalDateTime roundEndedAt = LocalDateTime.parse("2024-08-03T20:00:02"); + RoomContent roomContent = new RoomContent(ROOM, BALANCE_CONTENT, ROUND, roundEndedAt, IS_USED); + LocalDateTime now = LocalDateTime.parse("2024-08-03T20:00:03"); // when & then - assertThatCode(roomContent::validateAlreadyUsed).doesNotThrowAnyException(); + assertThat(roomContent.isRoundOver(now, ROUND)).isTrue(); } - } - - @Nested - class 라운드_일치_여부 { - - private static final LocalDateTime ROUND_ENDED_AT = LocalDateTime.parse("2024-08-03T20:00:02"); - private static final boolean IS_USED = false; @Test - void 라운드가_일치하지_않으면_예외가_발생한다() { + void 사용된_컨텐츠면_예외가_발생한다() { // given - int round = 2; - RoomContent roomContent = new RoomContent(ROOM, BALANCE_CONTENT, round, ROUND_ENDED_AT, IS_USED); - int invalidRound = 1; + boolean isUsed = true; + RoomContent roomContent = new RoomContent(ROOM, BALANCE_CONTENT, ROUND, ROUND_ENDED_AT, isUsed); + LocalDateTime now = LocalDateTime.parse("2024-08-03T20:00:01"); // when & then - assertThatThrownBy(() -> roomContent.validateSameRound(invalidRound)) + assertThatThrownBy(() -> roomContent.isRoundOver(now, ROUND)) .isExactlyInstanceOf(BadRequestException.class) - .hasMessageContaining("라운드가 일치하지 않습니다."); + .hasMessageContaining("이미 사용된 컨텐츠입니다."); } @Test - void 라운드가_일치하면_예외가_발생하지_않는다() { + void 라운드가_일치하지_않으면_예외가_발생한다() { // given - int round = 1; + int round = 2; RoomContent roomContent = new RoomContent(ROOM, BALANCE_CONTENT, round, ROUND_ENDED_AT, IS_USED); + int invalidRound = 1; + LocalDateTime now = LocalDateTime.parse("2024-08-03T20:00:01"); // when & then - assertThatCode(() -> roomContent.validateSameRound(round)).doesNotThrowAnyException(); + assertThatThrownBy(() -> roomContent.isRoundOver(now, invalidRound)) + .isExactlyInstanceOf(BadRequestException.class) + .hasMessageContaining("라운드가 일치하지 않습니다."); } } } diff --git a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java index 316490bd..5c0b08da 100644 --- a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java @@ -37,85 +37,108 @@ class BalanceVoteServiceTest extends BaseServiceTest { @Autowired private BalanceVoteService balanceVoteService; + private BalanceContent content; + + private BalanceOption optionA; + + private BalanceOption optionB; + + private Room room; + + private Member prin; + + private Member tacan; + + private Member keochan; + + private Member eden; + + @BeforeEach + void setUp() { + content = balanceContentRepository.save(new BalanceContent(Category.EXAMPLE, "A vs B")); + optionA = balanceOptionRepository.save(new BalanceOption("A", content)); + optionB = balanceOptionRepository.save(new BalanceOption("B", content)); + room = roomRepository.save(Room.createNewRoom()); + prin = memberRepository.save(PRIN.master(room)); + tacan = memberRepository.save(TACAN.common(room)); + keochan = memberRepository.save(KEOCHAN.common(room)); + eden = memberRepository.save(EDEN.common(room)); + } + @Nested @FixedClock(date = "2024-07-18", time = "20:00:02") class 투표_생성 { + private static final LocalDateTime ROUND_ENDED_AT = LocalDateTime.parse("2024-07-18T20:00:10"); + + @BeforeEach + void setUp() { + roomContentRepository.save(new RoomContent(room, content, 1, ROUND_ENDED_AT, false)); + } + @Test void 투표를_생성_할_수_있다() { // given - Long optionId = 1L; - Long contentId = 1L; - Long memberId = 1L; - Long roomId = 1L; - BalanceVoteResponse expected = new BalanceVoteResponse(optionId); + BalanceVoteRequest request = new BalanceVoteRequest(tacan.getId(), optionA.getId()); // when - BalanceVoteResponse actual = balanceVoteService.createBalanceVote( - new BalanceVoteRequest(memberId, optionId), roomId, contentId); + BalanceVoteResponse actual = balanceVoteService.createBalanceVote(request, room.getId(), content.getId()); // then - assertThat(actual).isEqualTo(expected); + assertThat(actual.optionId()).isEqualTo(optionA.getId()); } @Test - void 질문에_해당하는_선택지가_아닌_경우_예외를_던진다() { + @FixedClock(date = "2024-07-18", time = "20:00:11") + void 투표_시간이_지난_이후_투표_시_예외를_던진다() { // given - Long optionId = 3L; - Long contentId = 1L; - Long memberId = 1L; - Long roomId = 1L; + BalanceVoteRequest request = new BalanceVoteRequest(tacan.getId(), optionA.getId()); // when & then - assertThatThrownBy(() -> balanceVoteService.createBalanceVote( - new BalanceVoteRequest(memberId, optionId), roomId, contentId)) + assertThatThrownBy(() -> balanceVoteService.createBalanceVote(request, room.getId(), content.getId())) .isInstanceOf(BadRequestException.class) - .hasMessage("해당 질문의 선택지가 존재하지 않습니다."); + .hasMessage("이미 종료된 라운드에는 투표할 수 없습니다."); } @Test - void 방에_있지_않은_멤버인_경우_예외를_던진다() { + void 방의_현재_라운드와_다른_방_컨텐츠의_투표하면_예외를_던진다() { // given - Long optionId = 1L; - Long contentId = 1L; - Long memberId = 1L; - Long roomId = 3L; + BalanceContent content = balanceContentRepository.save(new BalanceContent(Category.EXAMPLE, "C vs D")); + BalanceOption optionC = balanceOptionRepository.save(new BalanceOption("C", content)); + balanceOptionRepository.save(new BalanceOption("D", content)); + int round = 2; + roomContentRepository.save(new RoomContent(room, content, round, ROUND_ENDED_AT, false)); + + BalanceVoteRequest request = new BalanceVoteRequest(tacan.getId(), optionC.getId()); // when & then - assertThatThrownBy(() -> balanceVoteService.createBalanceVote( - new BalanceVoteRequest(memberId, optionId), roomId, contentId)) + assertThatThrownBy(() -> balanceVoteService.createBalanceVote(request, room.getId(), content.getId())) .isInstanceOf(BadRequestException.class) - .hasMessage("해당 방의 멤버가 존재하지 않습니다."); + .hasMessage("컨텐츠의 라운드가 일치하지 않습니다. 방 컨텐츠의 라운드 : 2, 요청한 라운드 : 1"); } @Test - void 투표_시간이_지난_이후_투표_시_예외를_던진다() { + void 질문에_해당하는_선택지가_아닌_경우_예외를_던진다() { // given - Long optionId = 3L; - Long contentId = 2L; - Long memberId = 1L; - Long roomId = 1L; + Long invalidOptionId = 3L; + BalanceVoteRequest request = new BalanceVoteRequest(tacan.getId(), invalidOptionId); // when & then - assertThatThrownBy(() -> balanceVoteService.createBalanceVote( - new BalanceVoteRequest(memberId, optionId), roomId, contentId)) + assertThatThrownBy(() -> balanceVoteService.createBalanceVote(request, room.getId(), content.getId())) .isInstanceOf(BadRequestException.class) - .hasMessage("유효하지 않은 라운드에는 투표할 수 없습니다."); + .hasMessage("해당 질문의 선택지가 존재하지 않습니다."); } @Test - void 아직_진행하지_않은_컨텐츠에_투표_시_예외를_던진다() { + void 방에_있지_않은_멤버인_경우_예외를_던진다() { // given - Long optionId = 5L; - Long contentId = 3L; - Long memberId = 1L; - Long roomId = 1L; + Long invalidMemberId = 5L; + BalanceVoteRequest request = new BalanceVoteRequest(invalidMemberId, optionA.getId()); // when & then - assertThatThrownBy(() -> balanceVoteService.createBalanceVote( - new BalanceVoteRequest(memberId, optionId), roomId, contentId)) + assertThatThrownBy(() -> balanceVoteService.createBalanceVote(request, room.getId(), content.getId())) .isInstanceOf(BadRequestException.class) - .hasMessage("유효하지 않은 라운드에는 투표할 수 없습니다."); + .hasMessage("해당 방의 멤버가 존재하지 않습니다."); } } @@ -163,49 +186,20 @@ class 투표_종료_여부_조회 { private static final LocalDateTime ROUND_ENDED_AT = LocalDateTime.parse("2024-08-03T11:00:10"); private static final boolean IS_USED = false; - private Room room; - - private BalanceContent balanceContent; - - private BalanceOption optionA; - - private BalanceOption optionB; - - private Member prin; - - private Member tacan; - - private Member keochan; - - private Member eden; - - @BeforeEach - void setUp() { - balanceContent = balanceContentRepository.save(new BalanceContent(Category.EXAMPLE, "A vs B")); - optionA = balanceOptionRepository.save(new BalanceOption("A", balanceContent)); - optionB = balanceOptionRepository.save(new BalanceOption("B", balanceContent)); - - room = roomRepository.save(Room.createNewRoom()); - prin = memberRepository.save(PRIN.master(room)); - tacan = memberRepository.save(TACAN.common(room)); - keochan = memberRepository.save(KEOCHAN.common(room)); - eden = memberRepository.save(EDEN.common(room)); - } - @Test @FixedClock(date = "2024-08-03", time = "11:00:19") void 투표_제한_시간이_끝나지_않았지만_방의_모든_멤버가_컨텐츠에_투표했으면_모두_투표한_것이다() { // given int round = 1; LocalDateTime roundEndedAt = LocalDateTime.parse("2024-08-03T11:00:20"); - roomContentRepository.save(new RoomContent(room, balanceContent, round, roundEndedAt, IS_USED)); + roomContentRepository.save(new RoomContent(room, content, round, roundEndedAt, IS_USED)); balanceVoteRepository.save(new BalanceVote(optionA, prin)); balanceVoteRepository.save(new BalanceVote(optionA, tacan)); balanceVoteRepository.save(new BalanceVote(optionB, keochan)); balanceVoteRepository.save(new BalanceVote(optionB, eden)); // when - VoteFinishedResponse actual = balanceVoteService.getAllVoteFinished(room.getId(), balanceContent.getId()); + VoteFinishedResponse actual = balanceVoteService.getAllVoteFinished(room.getId(), content.getId()); // then assertThat(actual.isFinished()).isTrue(); @@ -217,10 +211,10 @@ void setUp() { // given int roomContentRound = 1; LocalDateTime roundEndedAt = LocalDateTime.parse("2024-08-03T11:00:20"); - roomContentRepository.save(new RoomContent(room, balanceContent, roomContentRound, roundEndedAt, IS_USED)); + roomContentRepository.save(new RoomContent(room, content, roomContentRound, roundEndedAt, IS_USED)); // when - VoteFinishedResponse actual = balanceVoteService.getAllVoteFinished(room.getId(), balanceContent.getId()); + VoteFinishedResponse actual = balanceVoteService.getAllVoteFinished(room.getId(), content.getId()); // then assertThat(actual.isFinished()).isTrue(); @@ -230,13 +224,13 @@ void setUp() { void 투표_제한_시간이_끝나지_않고_방의_모든_멤버가_투표하지_않았으면_모두_투표하지_않은_것이다() { // given int round = 1; - roomContentRepository.save(new RoomContent(room, balanceContent, round, ROUND_ENDED_AT, IS_USED)); + roomContentRepository.save(new RoomContent(room, content, round, ROUND_ENDED_AT, IS_USED)); balanceVoteRepository.save(new BalanceVote(optionA, prin)); balanceVoteRepository.save(new BalanceVote(optionA, tacan)); balanceVoteRepository.save(new BalanceVote(optionB, eden)); // when - VoteFinishedResponse actual = balanceVoteService.getAllVoteFinished(room.getId(), balanceContent.getId()); + VoteFinishedResponse actual = balanceVoteService.getAllVoteFinished(room.getId(), content.getId()); // then assertThat(actual.isFinished()).isFalse(); @@ -245,7 +239,7 @@ void setUp() { @Test void 방에_존재하지_않은_방_컨텐츠의_투표_여부를_조회하면_예외가_발생한다() { // when & then - assertThatThrownBy(() -> balanceVoteService.getAllVoteFinished(room.getId(), balanceContent.getId())) + assertThatThrownBy(() -> balanceVoteService.getAllVoteFinished(room.getId(), content.getId())) .isExactlyInstanceOf(BadRequestException.class) .hasMessageContaining("방에 존재하지 않은 컨텐츠입니다."); } @@ -254,10 +248,10 @@ void setUp() { void 방의_현재_라운드와_다른_방_컨텐츠의_투표_여부를_조회하면_예외가_발생한다() { // given int round = 2; - roomContentRepository.save(new RoomContent(room, balanceContent, round, ROUND_ENDED_AT, IS_USED)); + roomContentRepository.save(new RoomContent(room, content, round, ROUND_ENDED_AT, IS_USED)); // when & then - assertThatThrownBy(() -> balanceVoteService.getAllVoteFinished(room.getId(), balanceContent.getId())) + assertThatThrownBy(() -> balanceVoteService.getAllVoteFinished(room.getId(), content.getId())) .isExactlyInstanceOf(BadRequestException.class) .hasMessageContaining("컨텐츠의 라운드가 일치하지 않습니다. 방 컨텐츠의 라운드 : 2, 요청한 라운드 : 1"); } @@ -267,10 +261,10 @@ void setUp() { // given int round = 1; boolean isUsed = true; - roomContentRepository.save(new RoomContent(room, balanceContent, round, ROUND_ENDED_AT, isUsed)); + roomContentRepository.save(new RoomContent(room, content, round, ROUND_ENDED_AT, isUsed)); // when & then - assertThatThrownBy(() -> balanceVoteService.getAllVoteFinished(room.getId(), balanceContent.getId())) + assertThatThrownBy(() -> balanceVoteService.getAllVoteFinished(room.getId(), content.getId())) .isExactlyInstanceOf(BadRequestException.class) .hasMessageContaining("이미 사용된 컨텐츠입니다."); } From 8bac7c11889c173c47253ea95bf17f319f76697f Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Sun, 4 Aug 2024 14:58:48 +0900 Subject: [PATCH 0526/1013] =?UTF-8?q?fix:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20render=20=ED=94=84=EB=A1=9C=ED=8D=BC=ED=8B=B0=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/SelectOption/SelectOption.stories.tsx | 12 ++---------- .../TabContentContainer.stories.tsx | 2 -- frontend/src/components/Timer/Timer.stories.tsx | 5 +---- .../TopicContainer/TopicContainer.stories.tsx | 4 +--- .../src/components/common/Button/Button.stories.tsx | 7 ------- 5 files changed, 4 insertions(+), 26 deletions(-) diff --git a/frontend/src/components/SelectOption/SelectOption.stories.tsx b/frontend/src/components/SelectOption/SelectOption.stories.tsx index 376ef2a2..f3505039 100644 --- a/frontend/src/components/SelectOption/SelectOption.stories.tsx +++ b/frontend/src/components/SelectOption/SelectOption.stories.tsx @@ -5,11 +5,6 @@ import SelectOption from './SelectOption'; const meta = { title: 'SelectOption', - parameters: { - argTypes: {}, - actions: { argTypesRegex: '^on.*' }, - }, - args: { handleSelectOption: fn() }, component: SelectOption, @@ -24,14 +19,11 @@ export const 선택되지_않은_옵션: Story = { option: { name: '100억 빚 송강', optionId: 1 }, selectedId: 0, }, - render: ({ ...args }) => , }; export const 선택된_옵션: Story = { args: { - option: { name: '100억 빚 송강', optionId: 1 }, - selectedId: 1, + option: { name: '100억 부자 송강호', optionId: 2 }, + selectedId: 2, }, - - render: (args) => , }; diff --git a/frontend/src/components/TabContentContainer/TabContentContainer.stories.tsx b/frontend/src/components/TabContentContainer/TabContentContainer.stories.tsx index 70af96df..205e98d1 100644 --- a/frontend/src/components/TabContentContainer/TabContentContainer.stories.tsx +++ b/frontend/src/components/TabContentContainer/TabContentContainer.stories.tsx @@ -15,12 +15,10 @@ export const 그룹_탭: Story = { args: { isGroupTabActive: true, }, - render: (args) => , }; export const 전체_탭: Story = { args: { isGroupTabActive: false, }, - render: (args) => , }; diff --git a/frontend/src/components/Timer/Timer.stories.tsx b/frontend/src/components/Timer/Timer.stories.tsx index 47e6f978..91fcde20 100644 --- a/frontend/src/components/Timer/Timer.stories.tsx +++ b/frontend/src/components/Timer/Timer.stories.tsx @@ -11,7 +11,4 @@ type Story = StoryObj; export default meta; -export const 기본_타이머: Story = { - args: {}, - render: (args) => , -}; +export const 기본_타이머: Story = {}; diff --git a/frontend/src/components/TopicContainer/TopicContainer.stories.tsx b/frontend/src/components/TopicContainer/TopicContainer.stories.tsx index 257e4c9b..a5c83753 100644 --- a/frontend/src/components/TopicContainer/TopicContainer.stories.tsx +++ b/frontend/src/components/TopicContainer/TopicContainer.stories.tsx @@ -11,6 +11,4 @@ export default meta; type Story = StoryObj; -export const 기본_카테고리_및_질문: Story = { - render: (args) => , -}; +export const 기본_카테고리_및_질문: Story = {}; diff --git a/frontend/src/components/common/Button/Button.stories.tsx b/frontend/src/components/common/Button/Button.stories.tsx index e0b13e71..c4ea47a4 100644 --- a/frontend/src/components/common/Button/Button.stories.tsx +++ b/frontend/src/components/common/Button/Button.stories.tsx @@ -5,13 +5,7 @@ import Button from './Button'; const meta = { title: 'Button', - parameters: { - argTypes: {}, - actions: { argTypesRegex: '^on.*' }, - }, - args: { onClick: fn() }, - component: Button, } satisfies Meta; @@ -24,5 +18,4 @@ export const 기본_버튼: Story = { text: '선택', disabled: false, }, - render: ({ ...args }) =>
    ); }; From d4a0ef08434b327fd3c667aee8096ce0a5222cc6 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Mon, 5 Aug 2024 01:30:01 +0900 Subject: [PATCH 0541/1013] =?UTF-8?q?refactor:=20=EC=BB=A8=EB=B2=A4?= =?UTF-8?q?=EC=85=98=EC=97=90=20=EB=94=B0=EB=9D=BC=20export=20=EB=B0=A9?= =?UTF-8?q?=EC=8B=9D=20=EC=88=98=EC=A0=95=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/GameResult/GameResult.hook.ts | 2 +- frontend/src/components/GameResult/GameResult.tsx | 2 +- .../RoundVoteContainer/RoundVoteContainer.hook.ts | 4 +++- .../components/TabContentContainer/TabContentContainer.tsx | 2 +- frontend/src/components/Timer/Timer.hook.ts | 4 +++- frontend/src/components/Timer/Timer.test.tsx | 2 +- frontend/src/components/Timer/Timer.tsx | 4 ++-- frontend/src/components/Timer/Timer.util.ts | 4 +++- .../common/NextRoundButton/NextRoundButton.hook.ts | 4 +++- .../components/common/NextRoundButton/NextRoundButton.tsx | 2 +- .../components/common/SelectButton/SelectButton.hook.ts | 7 +++---- .../src/components/common/SelectButton/SelectButton.tsx | 2 +- 12 files changed, 23 insertions(+), 16 deletions(-) diff --git a/frontend/src/components/GameResult/GameResult.hook.ts b/frontend/src/components/GameResult/GameResult.hook.ts index 3817e977..7f846641 100644 --- a/frontend/src/components/GameResult/GameResult.hook.ts +++ b/frontend/src/components/GameResult/GameResult.hook.ts @@ -17,4 +17,4 @@ const useGameResultQuery = (): GameResultQueryResponse => { return { ...gameResultQuery, gameResult: gameResultQuery.data }; }; -export { useGameResultQuery }; +export default useGameResultQuery; diff --git a/frontend/src/components/GameResult/GameResult.tsx b/frontend/src/components/GameResult/GameResult.tsx index 615eaeaf..0db449a8 100644 --- a/frontend/src/components/GameResult/GameResult.tsx +++ b/frontend/src/components/GameResult/GameResult.tsx @@ -1,4 +1,4 @@ -import { useGameResultQuery } from './GameResult.hook'; +import useGameResultQuery from './GameResult.hook'; import { gameResultTitle, gameResultLayout, rankListContainer } from './GameResult.styled'; import FinalButton from '../common/FinalButton/FinalButton'; import GameResultItem from '../GameResultItem/GameResultItem'; diff --git a/frontend/src/components/RoundVoteContainer/RoundVoteContainer.hook.ts b/frontend/src/components/RoundVoteContainer/RoundVoteContainer.hook.ts index 5e5672d8..d69c6cad 100644 --- a/frontend/src/components/RoundVoteContainer/RoundVoteContainer.hook.ts +++ b/frontend/src/components/RoundVoteContainer/RoundVoteContainer.hook.ts @@ -1,7 +1,7 @@ import useCountAnimation from '@/hooks/useCountAnimation'; import { Total, Group } from '@/types/roundVoteResult'; -export const useTotalCountAnimation = (groupRoundResult?: Group, totalResult?: Total) => { +const useTotalCountAnimation = (groupRoundResult?: Group, totalResult?: Total) => { const animatedFirstPercent = useCountAnimation({ target: groupRoundResult?.firstOption.percent }); const animatedSecondPercent = useCountAnimation({ target: groupRoundResult?.secondOption.percent, @@ -19,3 +19,5 @@ export const useTotalCountAnimation = (groupRoundResult?: Group, totalResult?: T animatedTotalSecondPercent, }; }; + +export default useTotalCountAnimation; diff --git a/frontend/src/components/TabContentContainer/TabContentContainer.tsx b/frontend/src/components/TabContentContainer/TabContentContainer.tsx index ee6bd9f3..5b58b51c 100644 --- a/frontend/src/components/TabContentContainer/TabContentContainer.tsx +++ b/frontend/src/components/TabContentContainer/TabContentContainer.tsx @@ -12,7 +12,7 @@ import { roundVoteResultContainer, secondBar, } from './TabContentContainer.styled'; -import { useTotalCountAnimation } from '../RoundVoteContainer/RoundVoteContainer.hook'; +import useTotalCountAnimation from '../RoundVoteContainer/RoundVoteContainer.hook'; import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; import useRoundVoteResultQuery from '@/hooks/useRoundVoteResultQuery'; diff --git a/frontend/src/components/Timer/Timer.hook.ts b/frontend/src/components/Timer/Timer.hook.ts index 321eb3d9..7f3de408 100644 --- a/frontend/src/components/Timer/Timer.hook.ts +++ b/frontend/src/components/Timer/Timer.hook.ts @@ -5,7 +5,7 @@ import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; const INITIAL_WIDTH = 100; const DELAY = 1000; -export const useRoundTimer = () => { +const useRoundTimer = () => { const { balanceContent } = useBalanceContentQuery(); const timeLimit = balanceContent?.timeLimit || 30; @@ -39,3 +39,5 @@ export const useRoundTimer = () => { return { timerCount, barWidth, isAlmostFinished }; }; + +export default useRoundTimer; diff --git a/frontend/src/components/Timer/Timer.test.tsx b/frontend/src/components/Timer/Timer.test.tsx index ce7cdbca..058b856a 100644 --- a/frontend/src/components/Timer/Timer.test.tsx +++ b/frontend/src/components/Timer/Timer.test.tsx @@ -1,4 +1,4 @@ -import { formatTimer } from './Timer.util'; +import formatTimer from './Timer.util'; describe('Timer 테스트', () => { describe('formatTimer 유틸 함수 테스트', () => { diff --git a/frontend/src/components/Timer/Timer.tsx b/frontend/src/components/Timer/Timer.tsx index 2ead678f..9c7fc5db 100644 --- a/frontend/src/components/Timer/Timer.tsx +++ b/frontend/src/components/Timer/Timer.tsx @@ -1,4 +1,4 @@ -import { useRoundTimer } from './Timer.hook'; +import useRoundTimer from './Timer.hook'; import { timerIcon, timerIconShake, @@ -7,7 +7,7 @@ import { timerText, timerWrapper, } from './Timer.styled'; -import { formatTimer } from './Timer.util'; +import formatTimer from './Timer.util'; import Ddangkong from '@/assets/images/ddangkong.png'; diff --git a/frontend/src/components/Timer/Timer.util.ts b/frontend/src/components/Timer/Timer.util.ts index 65295eca..3b7131c9 100644 --- a/frontend/src/components/Timer/Timer.util.ts +++ b/frontend/src/components/Timer/Timer.util.ts @@ -1,4 +1,4 @@ -export const formatTimer = (timer: number) => { +const formatTimer = (timer: number) => { const minutes = Math.floor(timer / 60); const seconds = timer % 60; @@ -7,3 +7,5 @@ export const formatTimer = (timer: number) => { return `${formattedMinutes}:${formattedSeconds}`; }; + +export default formatTimer; diff --git a/frontend/src/components/common/NextRoundButton/NextRoundButton.hook.ts b/frontend/src/components/common/NextRoundButton/NextRoundButton.hook.ts index 83044679..0cc8f8dc 100644 --- a/frontend/src/components/common/NextRoundButton/NextRoundButton.hook.ts +++ b/frontend/src/components/common/NextRoundButton/NextRoundButton.hook.ts @@ -3,7 +3,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { moveNextRound } from '@/apis/balanceContent'; import { QUERY_KEYS } from '@/constants/queryKeys'; -export const useMoveNextRoundMutation = () => { +const useMoveNextRoundMutation = () => { const queryClient = useQueryClient(); return useMutation({ @@ -13,3 +13,5 @@ export const useMoveNextRoundMutation = () => { }, }); }; + +export default useMoveNextRoundMutation; diff --git a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx index 531cd275..6e287629 100644 --- a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx +++ b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx @@ -1,6 +1,6 @@ import { useNavigate } from 'react-router-dom'; -import { useMoveNextRoundMutation } from './NextRoundButton.hook'; +import useMoveNextRoundMutation from './NextRoundButton.hook'; import Button from '../Button/Button'; import { bottomButtonLayout } from '../Button/Button.styled'; diff --git a/frontend/src/components/common/SelectButton/SelectButton.hook.ts b/frontend/src/components/common/SelectButton/SelectButton.hook.ts index ea8c020e..0ff95adf 100644 --- a/frontend/src/components/common/SelectButton/SelectButton.hook.ts +++ b/frontend/src/components/common/SelectButton/SelectButton.hook.ts @@ -8,10 +8,7 @@ interface UseSelectCompleteMutationProps { contentId?: number; } -export const useSelectCompleteMutation = ({ - selectedId, - contentId, -}: UseSelectCompleteMutationProps) => { +const useSelectCompleteMutation = ({ selectedId, contentId }: UseSelectCompleteMutationProps) => { const { roomId } = useParams(); return useMutation({ @@ -28,3 +25,5 @@ export const useSelectCompleteMutation = ({ }, }); }; + +export default useSelectCompleteMutation; diff --git a/frontend/src/components/common/SelectButton/SelectButton.tsx b/frontend/src/components/common/SelectButton/SelectButton.tsx index 7042ba16..bd7bc5b5 100644 --- a/frontend/src/components/common/SelectButton/SelectButton.tsx +++ b/frontend/src/components/common/SelectButton/SelectButton.tsx @@ -1,4 +1,4 @@ -import { useSelectCompleteMutation } from './SelectButton.hook'; +import useSelectCompleteMutation from './SelectButton.hook'; import Button from '../Button/Button'; import { bottomButtonLayout } from '../Button/Button.styled'; From 6b5e73e7c561e7f226b6ee4b43b5cdb56650d955 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Mon, 5 Aug 2024 01:39:01 +0900 Subject: [PATCH 0542/1013] =?UTF-8?q?refactor:=20=ED=83=80=EC=9D=B4?= =?UTF-8?q?=EB=A8=B8=EB=A5=BC=20=EB=82=98=ED=83=80=EB=82=B4=EB=8A=94=20?= =?UTF-8?q?=EB=AA=85=EC=8B=9C=EC=A0=81=EC=9D=B8=20=EB=B3=80=EC=88=98?= =?UTF-8?q?=EB=AA=85=EC=9C=BC=EB=A1=9C=20=EC=88=98=EC=A0=95=20#97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/Timer/Timer.hook.ts | 18 +++++++++--------- frontend/src/components/Timer/Timer.tsx | 10 +++++----- frontend/src/components/Timer/Timer.util.ts | 8 ++++---- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/frontend/src/components/Timer/Timer.hook.ts b/frontend/src/components/Timer/Timer.hook.ts index 7f3de408..f33aa26c 100644 --- a/frontend/src/components/Timer/Timer.hook.ts +++ b/frontend/src/components/Timer/Timer.hook.ts @@ -9,27 +9,27 @@ const useRoundTimer = () => { const { balanceContent } = useBalanceContentQuery(); const timeLimit = balanceContent?.timeLimit || 30; - const [timerCount, setTimerCount] = useState(timeLimit); - const [barWidth, setBarWidth] = useState(INITIAL_WIDTH); - const isAlmostFinished = timerCount <= 5; + const [leftRoundTime, setLeftRoundTime] = useState(timeLimit); + const [barWidthPercent, setBarWidthPercent] = useState(INITIAL_WIDTH); + const isAlmostFinished = leftRoundTime <= 5; const timeout = useRef(); useEffect(() => { - if (timerCount <= 0) { + if (leftRoundTime <= 0) { clearInterval(timeout.current); } - }, [timerCount]); + }, [leftRoundTime]); useEffect(() => { if (!balanceContent) return; const DECREASE_RATE = INITIAL_WIDTH / timeLimit; - setTimerCount(timeLimit); + setLeftRoundTime(timeLimit); timeout.current = setInterval(() => { - setTimerCount((prev) => prev - 1); - setBarWidth((prevWidth) => (prevWidth > 0 ? prevWidth - DECREASE_RATE : 0)); + setLeftRoundTime((prev) => prev - 1); + setBarWidthPercent((prevWidth) => (prevWidth > 0 ? prevWidth - DECREASE_RATE : 0)); }, DELAY); return () => { @@ -37,7 +37,7 @@ const useRoundTimer = () => { }; }, [balanceContent, timeLimit]); - return { timerCount, barWidth, isAlmostFinished }; + return { leftRoundTime, barWidthPercent, isAlmostFinished }; }; export default useRoundTimer; diff --git a/frontend/src/components/Timer/Timer.tsx b/frontend/src/components/Timer/Timer.tsx index 9c7fc5db..be15bd8a 100644 --- a/frontend/src/components/Timer/Timer.tsx +++ b/frontend/src/components/Timer/Timer.tsx @@ -7,19 +7,19 @@ import { timerText, timerWrapper, } from './Timer.styled'; -import formatTimer from './Timer.util'; +import formatLeftRoundTime from './Timer.util'; import Ddangkong from '@/assets/images/ddangkong.png'; const Timer = () => { - const { barWidth, timerCount, isAlmostFinished } = useRoundTimer(); + const { barWidthPercent, leftRoundTime, isAlmostFinished } = useRoundTimer(); return (
    -
    -
    +
    +
    타이머 - {formatTimer(timerCount)} + {formatLeftRoundTime(leftRoundTime)}
    ); diff --git a/frontend/src/components/Timer/Timer.util.ts b/frontend/src/components/Timer/Timer.util.ts index 3b7131c9..b365bf5f 100644 --- a/frontend/src/components/Timer/Timer.util.ts +++ b/frontend/src/components/Timer/Timer.util.ts @@ -1,6 +1,6 @@ -const formatTimer = (timer: number) => { - const minutes = Math.floor(timer / 60); - const seconds = timer % 60; +const formatLeftRoundTime = (leftRoundTime: number) => { + const minutes = Math.floor(leftRoundTime / 60); + const seconds = leftRoundTime % 60; const formattedMinutes = String(minutes).padStart(2, '0'); const formattedSeconds = String(seconds).padStart(2, '0'); @@ -8,4 +8,4 @@ const formatTimer = (timer: number) => { return `${formattedMinutes}:${formattedSeconds}`; }; -export default formatTimer; +export default formatLeftRoundTime; From 4842091628e5b9b6480d38854bcea3f9412afadf Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Mon, 5 Aug 2024 09:09:36 +0900 Subject: [PATCH 0543/1013] =?UTF-8?q?chore:=20storybook=20url=EC=9D=84=20?= =?UTF-8?q?=EC=9E=90=EB=8F=99=EC=9C=BC=EB=A1=9C=20=EC=BD=94=EB=A9=98?= =?UTF-8?q?=ED=8A=B8=EC=97=90=20=EB=82=A8=EA=B8=B0=EB=8A=94=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EC=9E=91=EC=84=B1=20#125?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/fe-cd-storybook.yml | 16 ++++++++++++++-- .github/workflows/fe-ci-dev.yml | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/workflows/fe-cd-storybook.yml b/.github/workflows/fe-cd-storybook.yml index 46b287b1..b4213823 100644 --- a/.github/workflows/fe-cd-storybook.yml +++ b/.github/workflows/fe-cd-storybook.yml @@ -1,4 +1,4 @@ -name: storybook deploy +name: FE CD storybook on: pull_request: @@ -12,7 +12,7 @@ jobs: defaults: run: working-directory: frontend - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest permissions: contents: write concurrency: @@ -39,3 +39,15 @@ jobs: github_token: ${{ secrets.TOKEN }} publish_dir: ./frontend/storybook-static destination_dir: storybook + + - name: comment storybook url + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.TOKEN }} + script: | + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: '🎀 storybook 배포 주소 : https://woowacourse-teams.github.io/2024-ddangkong/storybook/' + }) diff --git a/.github/workflows/fe-ci-dev.yml b/.github/workflows/fe-ci-dev.yml index 3e7271fd..88a32ebc 100644 --- a/.github/workflows/fe-ci-dev.yml +++ b/.github/workflows/fe-ci-dev.yml @@ -1,4 +1,4 @@ -name: Frontend CI +name: FE CI for dev on: pull_request: From 0b89249ec45d7be0e1a2840e1451a02e5783490d Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Mon, 5 Aug 2024 09:54:29 +0900 Subject: [PATCH 0544/1013] =?UTF-8?q?refactor:=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EC=97=90=EC=84=9C=20=EC=83=9D=EC=84=B1=EC=9E=90?= =?UTF-8?q?=EB=A5=BC=20=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20#98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ddangkong/domain/balance/room/RoomContent.java | 9 ++++----- .../ddangkong/domain/balance/room/RoomContentTest.java | 6 +++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java index 2831b854..7beda4b1 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java @@ -44,11 +44,10 @@ public class RoomContent { @Column(nullable = false) private boolean isUsed; - public static RoomContent createNewRoom(Room room, BalanceContent balanceContent, int round) { - return new RoomContent(room, balanceContent, round, null, false); - } - - public RoomContent(Room room, BalanceContent balanceContent, int round, LocalDateTime roundEndedAt, + public RoomContent(Room room, + BalanceContent balanceContent, + int round, + LocalDateTime roundEndedAt, boolean isUsed) { this.room = room; this.balanceContent = balanceContent; diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java index 19dc1650..b8310e16 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java @@ -24,7 +24,7 @@ class 라운드_시작 { int currentRound = 1; int timeLimit = 10_000; Room room = new Room(5, currentRound, timeLimit, RoomStatus.PROGRESS, Category.EXAMPLE); - RoomContent roomContent = RoomContent.createNewRoom(room, BALANCE_CONTENT, currentRound); + RoomContent roomContent = new RoomContent(room, BALANCE_CONTENT, currentRound, null, false); int expectedAfterSec = (timeLimit + 2_000) / 1_000; LocalDateTime expectedRoundEnded = CURRENT_TIME.plusSeconds(expectedAfterSec); @@ -40,7 +40,7 @@ class 라운드_시작 { // given int currentRound = 1; Room room = new Room(5, currentRound, 10_000, RoomStatus.PROGRESS, Category.EXAMPLE); - RoomContent roomContent = RoomContent.createNewRoom(room, BALANCE_CONTENT, currentRound); + RoomContent roomContent = new RoomContent(room, BALANCE_CONTENT, currentRound, null, false); roomContent.startRound(CURRENT_TIME); // when & then @@ -55,7 +55,7 @@ class 라운드_시작 { int roomRound = 1; int roomContentRound = 2; Room room = new Room(5, roomRound, 10_000, RoomStatus.PROGRESS, Category.EXAMPLE); - RoomContent roomContent = RoomContent.createNewRoom(room, BALANCE_CONTENT, roomContentRound); + RoomContent roomContent = new RoomContent(room, BALANCE_CONTENT, roomContentRound, null, false); // when & then assertThatThrownBy(() -> roomContent.startRound(CURRENT_TIME)) From 152a0904bc9fd57bde894d1d7ac6961a35c36aca Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Mon, 5 Aug 2024 11:00:20 +0900 Subject: [PATCH 0545/1013] =?UTF-8?q?fix:=20API=20=EB=AA=85=EC=84=B8?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=9D=BC=20post=EB=A5=BC=20patch=EB=A1=9C?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=20#99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ddangkong/controller/balance/room/RoomController.java | 3 ++- .../ddangkong/controller/balance/room/RoomControllerTest.java | 4 ++-- .../documentation/balance/room/RoomDocumentationTest.java | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java index 2f41dbfa..c17fa49c 100644 --- a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java +++ b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java @@ -11,6 +11,7 @@ import org.springframework.http.HttpStatus; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -50,7 +51,7 @@ public BalanceContentResponse moveToNextRound(@PathVariable @Positive Long roomI } @ResponseStatus(HttpStatus.NO_CONTENT) - @PostMapping("/balances/rooms/{roomId}/start") + @PatchMapping("/balances/rooms/{roomId}/start") public void startGame(@PathVariable @Positive Long roomId) { roomService.startGame(roomId); } diff --git a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java index 39770b89..d265f4f6 100644 --- a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java @@ -129,7 +129,7 @@ class 게임_시작 { // when & then RestAssured.given().log().all() .pathParam("roomId", READY_ROOM_ID) - .when().post("/api/balances/rooms/{roomId}/start") + .when().patch("/api/balances/rooms/{roomId}/start") .then().log().all() .statusCode(204); } @@ -139,7 +139,7 @@ class 게임_시작 { // when & then RestAssured.given().log().all() .pathParam("roomId", -1L) - .when().post("/api/balances/rooms/{roomId}/start") + .when().patch("/api/balances/rooms/{roomId}/start") .then().log().all() .statusCode(400); } diff --git a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java index 0444347b..2e1afe1a 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java @@ -1,11 +1,11 @@ package ddangkong.documentation.balance.room; - import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; import static org.springframework.restdocs.payload.JsonFieldType.BOOLEAN; import static org.springframework.restdocs.payload.JsonFieldType.NUMBER; @@ -167,7 +167,7 @@ class 게임_시작 { Long roomId = 1L; // when & then - mockMvc.perform(post(ENDPOINT, roomId)) + mockMvc.perform(patch(ENDPOINT, roomId)) .andExpect(status().isNoContent()) .andDo(document("room/start", pathParameters( From 14e0668ac74841065a05e698c1a156cbfbe0d899 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Mon, 5 Aug 2024 11:02:27 +0900 Subject: [PATCH 0546/1013] =?UTF-8?q?refactor:=20=EC=B6=94=ED=9B=84=20?= =?UTF-8?q?=EB=B0=98=ED=99=98=20=ED=98=95=ED=83=9C=20=EB=B3=80=EA=B2=BD?= =?UTF-8?q?=EC=9D=84=20=EB=8C=80=EB=B9=84=ED=95=B4=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD=20#99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - createList에서 createRoomContents로 변경 --- .../main/java/ddangkong/domain/balance/room/RoomContent.java | 2 +- .../main/java/ddangkong/service/balance/room/RoomService.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java index cb40709b..e70da730 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java @@ -43,7 +43,7 @@ public class RoomContent extends BaseEntity { @Column(nullable = false) private boolean isUsed; - public static List createList(Room room, List balanceContents) { + public static List createRoomContents(Room room, List balanceContents) { return IntStream.range(0, balanceContents.size()) .mapToObj(index -> new RoomContent(room, balanceContents.get(index), index + 1)) .toList(); diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index 69fca4ad..4ee2b8c4 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -62,7 +62,7 @@ public void startGame(Long roomId) { room.startGame(); List balanceContents = balanceContentRepository.findByRandom(room.getTotalRound()); - List roomContents = RoomContent.createList(room, balanceContents); + List roomContents = RoomContent.createRoomContents(room, balanceContents); startRound(roomContents.get(0)); roomContentRepository.saveAll(roomContents); } From 10e97e656b4ea4303cd9815fbb0419b4e237ec55 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Mon, 5 Aug 2024 11:05:27 +0900 Subject: [PATCH 0547/1013] =?UTF-8?q?test:=20`@CsvSource`=20=EB=8C=80?= =?UTF-8?q?=EC=8B=A0=20`@EnumSource`=20=EC=82=AC=EC=9A=A9=20#99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/java/ddangkong/domain/balance/room/RoomTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java index 0118b3f6..cfd56529 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java @@ -7,7 +7,8 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.EnumSource.Mode; class RoomTest { @@ -27,7 +28,7 @@ class 게임_시작 { } @ParameterizedTest - @CsvSource({"PROGRESS", "FINISH"}) + @EnumSource(mode = Mode.EXCLUDE, names = {"READY"}) void 게임이_이미_시작했다면_예외를_던진다(RoomStatus status) { // given Room room = new Room(5, 1, 30_000, status); From e0ddb4d8066b9baed00fb1d84c41084b44eced8e Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Mon, 5 Aug 2024 11:20:37 +0900 Subject: [PATCH 0548/1013] =?UTF-8?q?refactor:=20=EB=9E=9C=EB=8D=A4=20?= =?UTF-8?q?=EA=B8=B0=EB=B0=98=20=EC=A1=B0=ED=9A=8C=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=20=EB=B0=8F=20=EC=88=98=EC=A0=95=20#99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 조회 및 랜덤으로 섞는 기능을 서비스로 이동 - 카테고리 기반 추출 (Room의 카테고리 이용) -> Merge 시 도입 예정 - id 조회 대신 객체 전체 조회 - DB에서 조회 후 Suffle 도입 --- .../content/BalanceContentRepository.java | 20 ++----------------- .../service/balance/room/RoomService.java | 16 ++++++++++++++- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/content/BalanceContentRepository.java b/backend/src/main/java/ddangkong/domain/balance/content/BalanceContentRepository.java index 347bfeca..dda1f1c2 100644 --- a/backend/src/main/java/ddangkong/domain/balance/content/BalanceContentRepository.java +++ b/backend/src/main/java/ddangkong/domain/balance/content/BalanceContentRepository.java @@ -1,33 +1,17 @@ package ddangkong.domain.balance.content; -import static java.util.stream.Collectors.toList; - import ddangkong.exception.BadRequestException; -import ddangkong.exception.InternalServerException; -import java.util.Collections; import java.util.List; -import java.util.stream.LongStream; import org.springframework.data.jpa.repository.JpaRepository; public interface BalanceContentRepository extends JpaRepository { - long count(); + List findByCategory(Category category); - List findByIdIn(List ids); + long count(); default BalanceContent getById(Long id) { return findById(id) .orElseThrow(() -> new BadRequestException("해당 질문 컨텐츠가 존재하지 않습니다.")); } - - default List findByRandom(int count) { - List ids = LongStream.rangeClosed(1, count).boxed().collect(toList()); - if (ids.size() < count) { - throw new InternalServerException("질문이 라운드만큼 존재하지 않습니다."); - } - - Collections.shuffle(ids); - List candidateIds = ids.subList(0, count); - return findByIdIn(candidateIds); - } } diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index 4ee2b8c4..9482daca 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -6,6 +6,7 @@ import ddangkong.controller.balance.room.dto.RoomJoinResponse; import ddangkong.domain.balance.content.BalanceContent; import ddangkong.domain.balance.content.BalanceContentRepository; +import ddangkong.domain.balance.content.Category; import ddangkong.domain.balance.option.BalanceOptionRepository; import ddangkong.domain.balance.option.BalanceOptions; import ddangkong.domain.balance.room.Room; @@ -15,6 +16,8 @@ import ddangkong.domain.member.Member; import ddangkong.domain.member.MemberRepository; import ddangkong.exception.BadRequestException; +import ddangkong.exception.InternalServerException; +import java.util.Collections; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -61,12 +64,23 @@ public void startGame(Long roomId) { Room room = roomRepository.getById(roomId); room.startGame(); - List balanceContents = balanceContentRepository.findByRandom(room.getTotalRound()); + // TODO Room에 카테고리 도입 후 수정 + List balanceContents = findByRandom(Category.EXAMPLE, room.getTotalRound()); List roomContents = RoomContent.createRoomContents(room, balanceContents); startRound(roomContents.get(0)); roomContentRepository.saveAll(roomContents); } + private List findByRandom(Category category, int count) { + List contents = balanceContentRepository.findByCategory(category); + if (contents.size() < count) { + throw new InternalServerException("DB의 질문 수가 부족합니다. category : " + category); + } + + Collections.shuffle(contents); + return contents.subList(0, count); + } + private void startRound(RoomContent roomContent) { // TODO #109 머지 시 반영 } From cccb0a0e401da21db439877c47e8fafcc7a18fcc Mon Sep 17 00:00:00 2001 From: novice0840 Date: Mon, 5 Aug 2024 16:08:38 +0900 Subject: [PATCH 0549/1013] =?UTF-8?q?refactor:=20h2=20->=20span=20?= =?UTF-8?q?=ED=83=9C=EA=B7=B8=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20#92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/CategoryContainer/CategoryContainer.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/frontend/src/components/CategoryContainer/CategoryContainer.tsx b/frontend/src/components/CategoryContainer/CategoryContainer.tsx index 5341872e..90336843 100644 --- a/frontend/src/components/CategoryContainer/CategoryContainer.tsx +++ b/frontend/src/components/CategoryContainer/CategoryContainer.tsx @@ -1,5 +1,3 @@ -import React from 'react'; - import { categoryContainerLayout, title, subtitle } from './CategoryContainer.styled'; interface CategoryContainerProps { @@ -9,7 +7,7 @@ interface CategoryContainerProps { const CategoryContainer = ({ category }: CategoryContainerProps) => { return (
    -

    카테고리

    + 카테고리

    {category}

    ); From c1eda60f54ed618435b18491418adc7bfa9074f9 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Mon, 5 Aug 2024 16:36:24 +0900 Subject: [PATCH 0550/1013] =?UTF-8?q?refactor:=20=EB=8C=80=EA=B8=B0?= =?UTF-8?q?=EB=B0=A9=20=EC=B4=88=EB=8C=80=ED=95=98=EA=B8=B0=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EB=94=94=EC=9E=90=EC=9D=B8=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?#92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadyMembersContainer.styled.ts | 12 ++++++++++++ .../ReadyMembersContainer/ReadyMembersContainer.tsx | 11 +++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.styled.ts b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.styled.ts index 42f5d207..9768da5d 100644 --- a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.styled.ts +++ b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.styled.ts @@ -1,6 +1,7 @@ import { css } from '@emotion/react'; import { Theme } from '@/styles/Theme'; +import getBorderRadius from '@/styles/utils/getBorderRadius'; export const readyMembersContainerLayout = css` display: flex; @@ -16,6 +17,7 @@ export const membersContainer = css` background-color: ${Theme.color.peanut300}; + font-size: 1rem; font-weight: 600; overflow-y: scroll; @@ -42,6 +44,16 @@ export const memberList = css` gap: 2rem; `; +export const inviteButton = css` + display: flex; + align-items: center; + gap: 2rem; + font-size: 1rem; + width: 100%; + background-color: ${Theme.color.peanut400}; + border-radius: ${getBorderRadius('medium')}; +`; + export const memberItem = css` display: flex; align-items: center; diff --git a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx index fb379cb1..8cc76c7a 100644 --- a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx +++ b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx @@ -6,6 +6,7 @@ import { profileBox, memberStatus, membersContainer, + inviteButton, } from './ReadyMembersContainer.styled'; import crownIcon from '@/assets/images/crownIcon.png'; @@ -20,11 +21,13 @@ const ReadyMembersContainer = ({ members }: ReadyMembersContainerProps) => {

    총 인원 {members.length}명

      -
    • - -
      초대하기
    • {members.map((member) => (
    • From 01db5fcd4acb6b5e1e45a444b12872bf1c446960 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Mon, 5 Aug 2024 16:37:16 +0900 Subject: [PATCH 0551/1013] =?UTF-8?q?refactor:=20css=20=EC=88=9C=EC=84=9C?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=20#92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadyMembersContainer/ReadyMembersContainer.styled.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.styled.ts b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.styled.ts index 9768da5d..57154c93 100644 --- a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.styled.ts +++ b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.styled.ts @@ -17,8 +17,8 @@ export const membersContainer = css` background-color: ${Theme.color.peanut300}; - font-size: 1rem; font-weight: 600; + font-size: 1rem; overflow-y: scroll; @@ -48,10 +48,12 @@ export const inviteButton = css` display: flex; align-items: center; gap: 2rem; - font-size: 1rem; width: 100%; - background-color: ${Theme.color.peanut400}; border-radius: ${getBorderRadius('medium')}; + + background-color: ${Theme.color.peanut400}; + + font-size: 1rem; `; export const memberItem = css` From 5609a214808189e74523e52bea882fcdf9045e3e Mon Sep 17 00:00:00 2001 From: novice0840 Date: Mon, 5 Aug 2024 17:26:46 +0900 Subject: [PATCH 0552/1013] =?UTF-8?q?refactor:=20.env=20=EC=83=81=EC=88=98?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=20#92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/constants/queryKeys.ts | 1 + frontend/src/constants/url.ts | 2 +- frontend/src/pages/ReadyPage/useGetRoomInfo.ts | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/frontend/src/constants/queryKeys.ts b/frontend/src/constants/queryKeys.ts index a9ea1b82..1a10d82b 100644 --- a/frontend/src/constants/queryKeys.ts +++ b/frontend/src/constants/queryKeys.ts @@ -3,4 +3,5 @@ export const QUERY_KEYS = { gameResult: 'gameResult', roundVoteResult: 'roundVoteResult', roundIsFinished: 'roundIsFinished', + roomMembers: 'roomMembers', } as const; diff --git a/frontend/src/constants/url.ts b/frontend/src/constants/url.ts index cee5ebd6..f9f7e02b 100644 --- a/frontend/src/constants/url.ts +++ b/frontend/src/constants/url.ts @@ -1,4 +1,4 @@ -const BASE_URL = `http://${process.env.API_BASE_URL}`; +const BASE_URL = process.env.API_BASE_URL; export const API_URL = { balanceContent: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/content`, diff --git a/frontend/src/pages/ReadyPage/useGetRoomInfo.ts b/frontend/src/pages/ReadyPage/useGetRoomInfo.ts index 4f04bcc7..2676a9a9 100644 --- a/frontend/src/pages/ReadyPage/useGetRoomInfo.ts +++ b/frontend/src/pages/ReadyPage/useGetRoomInfo.ts @@ -9,7 +9,7 @@ export const useGetRoomInfo = () => { const { data, isLoading, isError } = useQuery({ queryKey: [QUERY_KEYS.roomMembers, Number(roomId)], - queryFn: ({ queryKey: [_, roomId] }) => getRoomInfo(roomId as number), + queryFn: ({ queryKey: [_, roomId] }) => getRoomInfo(Number(roomId)), refetchInterval: 1000, }); From ec5649d5b1a42c1b3f8aff1213ce986546fa09d8 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Mon, 5 Aug 2024 18:11:45 +0900 Subject: [PATCH 0553/1013] =?UTF-8?q?fix:=20github=20actions=20=EC=8B=A4?= =?UTF-8?q?=ED=96=89=20=ED=99=98=EA=B2=BD=20self-hosted=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20#138?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/fe-ci-dev.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/fe-ci-dev.yml b/.github/workflows/fe-ci-dev.yml index 3e7271fd..479ddef5 100644 --- a/.github/workflows/fe-ci-dev.yml +++ b/.github/workflows/fe-ci-dev.yml @@ -9,7 +9,8 @@ on: jobs: build-and-test: - runs-on: ubuntu-latest + timeout-minutes: 4 + runs-on: [self-hosted, linux, ARM64] steps: - uses: actions/checkout@v4 From 3d9bb1a766616d6cd0a6cb72730b6713a42f176f Mon Sep 17 00:00:00 2001 From: novice0840 Date: Mon, 5 Aug 2024 18:22:26 +0900 Subject: [PATCH 0554/1013] =?UTF-8?q?fix:=20github=20actions=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=ED=99=95=EC=9D=B8=20#138?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/fe-ci-dev.yml | 4 ++++ .../components/CategoryContainer/CategoryContainer.stories.ts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/fe-ci-dev.yml b/.github/workflows/fe-ci-dev.yml index 479ddef5..816d5cc3 100644 --- a/.github/workflows/fe-ci-dev.yml +++ b/.github/workflows/fe-ci-dev.yml @@ -12,6 +12,10 @@ jobs: timeout-minutes: 4 runs-on: [self-hosted, linux, ARM64] + defaults: + run: + working-directory: ./frontend + steps: - uses: actions/checkout@v4 diff --git a/frontend/src/components/CategoryContainer/CategoryContainer.stories.ts b/frontend/src/components/CategoryContainer/CategoryContainer.stories.ts index 67740942..12411565 100644 --- a/frontend/src/components/CategoryContainer/CategoryContainer.stories.ts +++ b/frontend/src/components/CategoryContainer/CategoryContainer.stories.ts @@ -8,7 +8,7 @@ const meta = { export const 기본값: Story = { args: { - category: '연애', + category: '재미', }, }; From 2ca10c8ccf54d80e5dfb48b91d56780622c859f5 Mon Sep 17 00:00:00 2001 From: jhon3242 Date: Mon, 5 Aug 2024 19:26:04 +0900 Subject: [PATCH 0555/1013] =?UTF-8?q?feat:=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B3=80=EA=B2=BD=20#113?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../balance/content/BalanceContentController.java | 2 +- .../balance/content/BalanceContentService.java | 14 +++++++------- .../content/BalanceContentDocumentationTest.java | 2 +- .../balance/content/BalanceContentServiceTest.java | 11 +++++------ 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/backend/src/main/java/ddangkong/controller/balance/content/BalanceContentController.java b/backend/src/main/java/ddangkong/controller/balance/content/BalanceContentController.java index d030f073..f8c9fb27 100644 --- a/backend/src/main/java/ddangkong/controller/balance/content/BalanceContentController.java +++ b/backend/src/main/java/ddangkong/controller/balance/content/BalanceContentController.java @@ -20,6 +20,6 @@ public class BalanceContentController { @GetMapping("/balances/rooms/{roomId}/content") public BalanceContentResponse getBalanceContent(@PathVariable @Positive Long roomId) { - return balanceContentService.findRecentBalanceContent(roomId); + return balanceContentService.getRecentBalanceContent(roomId); } } diff --git a/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java b/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java index 2bfa772e..239ea9b2 100644 --- a/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java +++ b/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java @@ -23,9 +23,11 @@ public class BalanceContentService { private final BalanceOptionRepository balanceOptionRepository; @Transactional(readOnly = true) - public BalanceContentResponse findRecentBalanceContent(Long roomId) { - Room room = findProgessingRoom(roomId); - RoomContent roomContent = findCurrentRoomContent(room); + public BalanceContentResponse getRecentBalanceContent(Long roomId) { + Room room = roomRepository.getById(roomId); + validateProgressing(room); + + RoomContent roomContent = getCurrentRoomContent(room); BalanceOptions balanceOptions = balanceOptionRepository.getBalanceOptionsByBalanceContent( roomContent.getBalanceContent()); @@ -35,15 +37,13 @@ public BalanceContentResponse findRecentBalanceContent(Long roomId) { .build(); } - private Room findProgessingRoom(Long roomId) { - Room room = roomRepository.getById(roomId); + private static void validateProgressing(Room room) { if (!room.isGameProgress()) { throw new BadRequestException("해당 방은 게임을 진행하고 있지 않습니다."); } - return room; } - private RoomContent findCurrentRoomContent(Room room) { + private RoomContent getCurrentRoomContent(Room room) { return roomContentRepository.findByRoomAndRoundAndIsUsed(room, room.getCurrentRound(), false) .orElseThrow(() -> new BadRequestException("해당 방의 현재 진행중인 질문이 존재하지 않습니다.")); } diff --git a/backend/src/test/java/ddangkong/documentation/balance/content/BalanceContentDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/content/BalanceContentDocumentationTest.java index 0546f6ee..f05c89f5 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/content/BalanceContentDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/content/BalanceContentDocumentationTest.java @@ -49,7 +49,7 @@ class 방의_콘텐츠_조회 { firstOptionResponse, secondOptionResponse ); - when(balanceContentService.findRecentBalanceContent(anyLong())).thenReturn(response); + when(balanceContentService.getRecentBalanceContent(anyLong())).thenReturn(response); // when & then mockMvc.perform(get(ENDPOINT, 1L) diff --git a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java index a3c4139e..b7c007c0 100644 --- a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java @@ -2,7 +2,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertAll; import ddangkong.controller.balance.content.dto.BalanceContentResponse; import ddangkong.controller.balance.option.dto.BalanceOptionResponse; @@ -39,7 +38,7 @@ class 현재_방의_밸런스_게임_내용_조회 { @Test void 방의_진행_중인_밸런스_게임_내용을_조회할_수_있다() { // when - BalanceContentResponse actual = balanceContentService.findRecentBalanceContent(PROGRESS_ROOM_ID); + BalanceContentResponse actual = balanceContentService.getRecentBalanceContent(PROGRESS_ROOM_ID); // then assertThat(actual).isEqualTo(BALANCE_CONTENT_RESPONSE); @@ -48,7 +47,7 @@ class 현재_방의_밸런스_게임_내용_조회 { @Test void 방이_없을_경우_예외를_던진다() { // when & then - assertThatThrownBy(() -> balanceContentService.findRecentBalanceContent(NOT_EXIST_ROOM_ID)) + assertThatThrownBy(() -> balanceContentService.getRecentBalanceContent(NOT_EXIST_ROOM_ID)) .isInstanceOf(BadRequestException.class) .hasMessage("해당 방이 존재하지 않습니다."); } @@ -56,7 +55,7 @@ class 현재_방의_밸런스_게임_내용_조회 { @Test void 방의_현재_라운드의_질문이_없을_경우_예외를_던진다() { // when & then - assertThatThrownBy(() -> balanceContentService.findRecentBalanceContent(NOT_PROGRESSED_ROOM_ID)) + assertThatThrownBy(() -> balanceContentService.getRecentBalanceContent(NOT_PROGRESSED_ROOM_ID)) .isInstanceOf(BadRequestException.class) .hasMessage("해당 방의 현재 진행중인 질문이 존재하지 않습니다."); } @@ -64,7 +63,7 @@ class 현재_방의_밸런스_게임_내용_조회 { @Test void 방의_준비_상태인_경우_예외를_던진다() { // when & then - assertThatThrownBy(() -> balanceContentService.findRecentBalanceContent(READY_ROOM_ID)) + assertThatThrownBy(() -> balanceContentService.getRecentBalanceContent(READY_ROOM_ID)) .isInstanceOf(BadRequestException.class) .hasMessage("해당 방은 게임을 진행하고 있지 않습니다."); } @@ -72,7 +71,7 @@ class 현재_방의_밸런스_게임_내용_조회 { @Test void 방이_종료_상태인_경우_예외를_던진다() { // when & then - assertThatThrownBy(() -> balanceContentService.findRecentBalanceContent(FINISHED_ROOM_ID)) + assertThatThrownBy(() -> balanceContentService.getRecentBalanceContent(FINISHED_ROOM_ID)) .isInstanceOf(BadRequestException.class) .hasMessage("해당 방은 게임을 진행하고 있지 않습니다."); } From 4b07594a7a045adb740107d19ac7f6c2b9affefa Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Mon, 5 Aug 2024 19:37:14 +0900 Subject: [PATCH 0556/1013] =?UTF-8?q?refactor:=20=ED=83=80=20=EB=8F=84?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=EC=97=90=20=EB=8C=80=ED=95=9C=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=EC=9D=84=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=EC=97=90=EC=84=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 한 도메인에 대해서는 내부 필드에서만 검증하도록 함 - 다른 도메인에 대한 검증은 서비스 레이어에서 실시 --- .../ddangkong/domain/balance/room/RoomContent.java | 8 -------- .../domain/balance/room/RoomContentTest.java | 14 -------------- 2 files changed, 22 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java index 7beda4b1..e5db4ffb 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java @@ -60,19 +60,11 @@ public void startRound(LocalDateTime currentTime) { if (roundEndedAt != null) { throw new BadRequestException("해당 라운드는 이미 시작했습니다."); } - if (room.isGameProgress() && isDifferentToRoomRound()) { - throw new BadRequestException("방이 해당 라운드가 아닙니다. roomRound : %d, contentRound : %d" - .formatted(room.getCurrentRound(), round)); - } int afterSec = (room.getTimeLimit() + DELAY_MSEC) / 1_000; roundEndedAt = currentTime.plusSeconds(afterSec); } - private boolean isDifferentToRoomRound() { - return round != room.getCurrentRound(); - } - public boolean isRoundOver(LocalDateTime currentTime) { return currentTime.isAfter(getRoundEndedAt()); } diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java index b8310e16..61a79725 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java @@ -48,19 +48,5 @@ class 라운드_시작 { .isInstanceOf(BadRequestException.class) .hasMessage("해당 라운드는 이미 시작했습니다."); } - - @Test - void 방의_진행_라운드와_일치하지_않으면_예외를_던진다() { - // given - int roomRound = 1; - int roomContentRound = 2; - Room room = new Room(5, roomRound, 10_000, RoomStatus.PROGRESS, Category.EXAMPLE); - RoomContent roomContent = new RoomContent(room, BALANCE_CONTENT, roomContentRound, null, false); - - // when & then - assertThatThrownBy(() -> roomContent.startRound(CURRENT_TIME)) - .isInstanceOf(BadRequestException.class) - .hasMessage("방이 해당 라운드가 아닙니다. roomRound : 1, contentRound : 2"); - } } } From 02071397a402babb6849f55f2ed22bb583038bb0 Mon Sep 17 00:00:00 2001 From: jhon3242 Date: Mon, 5 Aug 2024 19:37:20 +0900 Subject: [PATCH 0557/1013] =?UTF-8?q?test:=20isInstanceOf=20->=20isExactly?= =?UTF-8?q?InstanceOf=20=EB=B3=80=EA=B2=BD=20#113?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../balance/content/BalanceContentServiceTest.java | 12 ++++++------ .../service/balance/room/RoomServiceTest.java | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java index b7c007c0..63e2fbe0 100644 --- a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java @@ -21,7 +21,7 @@ class BalanceContentServiceTest extends BaseServiceTest { class 현재_방의_밸런스_게임_내용_조회 { private static final Long PROGRESS_ROOM_ID = 1L; - private static final Long NOT_EXIST_ROOM_ID = 99999999L; + private static final Long NOT_EXIST_ROOM_ID = -1L; private static final Long NOT_PROGRESSED_ROOM_ID = 2L; private static final Long READY_ROOM_ID = 4L; private static final Long FINISHED_ROOM_ID = 5L; @@ -48,7 +48,7 @@ class 현재_방의_밸런스_게임_내용_조회 { void 방이_없을_경우_예외를_던진다() { // when & then assertThatThrownBy(() -> balanceContentService.getRecentBalanceContent(NOT_EXIST_ROOM_ID)) - .isInstanceOf(BadRequestException.class) + .isExactlyInstanceOf(BadRequestException.class) .hasMessage("해당 방이 존재하지 않습니다."); } @@ -56,15 +56,15 @@ class 현재_방의_밸런스_게임_내용_조회 { void 방의_현재_라운드의_질문이_없을_경우_예외를_던진다() { // when & then assertThatThrownBy(() -> balanceContentService.getRecentBalanceContent(NOT_PROGRESSED_ROOM_ID)) - .isInstanceOf(BadRequestException.class) + .isExactlyInstanceOf(BadRequestException.class) .hasMessage("해당 방의 현재 진행중인 질문이 존재하지 않습니다."); } @Test - void 방의_준비_상태인_경우_예외를_던진다() { + void 방이_준비_상태인_경우_예외를_던진다() { // when & then assertThatThrownBy(() -> balanceContentService.getRecentBalanceContent(READY_ROOM_ID)) - .isInstanceOf(BadRequestException.class) + .isExactlyInstanceOf(BadRequestException.class) .hasMessage("해당 방은 게임을 진행하고 있지 않습니다."); } @@ -72,7 +72,7 @@ class 현재_방의_밸런스_게임_내용_조회 { void 방이_종료_상태인_경우_예외를_던진다() { // when & then assertThatThrownBy(() -> balanceContentService.getRecentBalanceContent(FINISHED_ROOM_ID)) - .isInstanceOf(BadRequestException.class) + .isExactlyInstanceOf(BadRequestException.class) .hasMessage("해당 방은 게임을 진행하고 있지 않습니다."); } } diff --git a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java index b067690a..38500df1 100644 --- a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java @@ -99,7 +99,7 @@ class 방_참여 { // when & then assertThatThrownBy(() -> roomService.joinRoom(nickname, nonExistId)) - .isInstanceOf(BadRequestException.class); + .isExactlyInstanceOf(BadRequestException.class); } } @@ -132,7 +132,7 @@ class 다음_라운드로_이동 { void 방이_없을_경우_예외를_던진다() { // when & then assertThatThrownBy(() -> roomService.moveToNextRound(NOT_EXIST_ROOM_ID)) - .isInstanceOf(BadRequestException.class) + .isExactlyInstanceOf(BadRequestException.class) .hasMessage("해당 방이 존재하지 않습니다."); } @@ -140,7 +140,7 @@ class 다음_라운드로_이동 { void 방의_현재_라운드의_질문이_없을_경우_예외를_던진다() { // when & then assertThatThrownBy(() -> roomService.moveToNextRound(NOT_PROGRESSED_ROOM_ID)) - .isInstanceOf(BadRequestException.class) + .isExactlyInstanceOf(BadRequestException.class) .hasMessage("해당 방의 현재 진행중인 질문이 존재하지 않습니다."); } } From da0b830e50db5d36e002eae72e78130191778296 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Mon, 5 Aug 2024 20:33:11 +0900 Subject: [PATCH 0558/1013] =?UTF-8?q?refactor:=20timeLimit=EC=9D=84=20?= =?UTF-8?q?=EC=99=B8=EB=B6=80=EC=97=90=EC=84=9C=20=EC=9D=B8=EC=9E=90?= =?UTF-8?q?=EB=A1=9C=20=EB=B0=9B=EC=95=84=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ddangkong/domain/balance/room/RoomContent.java | 4 ++-- .../java/ddangkong/service/balance/room/RoomService.java | 2 +- .../java/ddangkong/domain/balance/room/RoomContentTest.java | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java index 144a5287..ca875be3 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java @@ -55,12 +55,12 @@ public RoomContent(Room room, this.isUsed = isUsed; } - public void startRound(LocalDateTime currentTime) { + public void startRound(LocalDateTime currentTime, int timeLimit) { if (roundEndedAt != null) { throw new BadRequestException("해당 라운드는 이미 시작했습니다."); } - int afterSec = (room.getTimeLimit() + DELAY_MSEC) / 1_000; + int afterSec = (timeLimit + DELAY_MSEC) / 1_000; roundEndedAt = currentTime.plusSeconds(afterSec); } diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index 1ff51ca6..6ddb0132 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -69,7 +69,7 @@ public void moveToNextRound(Long roomId) { if (room.isGameProgress()) { RoomContent roomContent = getCurrentRoomContent(room); - roomContent.startRound(LocalDateTime.now(clock)); + roomContent.startRound(LocalDateTime.now(clock), room.getTimeLimit()); } } diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java index a0dca098..078ee604 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomContentTest.java @@ -29,7 +29,7 @@ class 라운드_시작 { LocalDateTime expectedRoundEnded = CURRENT_TIME.plusSeconds(expectedAfterSec); // when - roomContent.startRound(CURRENT_TIME); + roomContent.startRound(CURRENT_TIME, timeLimit); // then assertThat(roomContent.getRoundEndedAt()).isEqualTo(expectedRoundEnded); @@ -41,10 +41,10 @@ class 라운드_시작 { int currentRound = 1; Room room = new Room(5, currentRound, 10_000, RoomStatus.PROGRESS, Category.EXAMPLE); RoomContent roomContent = new RoomContent(room, BALANCE_CONTENT, currentRound, null, false); - roomContent.startRound(CURRENT_TIME); + roomContent.startRound(CURRENT_TIME, 10_000); // when & then - assertThatThrownBy(() -> roomContent.startRound(CURRENT_TIME)) + assertThatThrownBy(() -> roomContent.startRound(CURRENT_TIME, 10_000)) .isInstanceOf(BadRequestException.class) .hasMessage("해당 라운드는 이미 시작했습니다."); } From b9e3db5b01a89a2f156f7bcd53d5da011440157d Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Mon, 5 Aug 2024 21:15:18 +0900 Subject: [PATCH 0559/1013] =?UTF-8?q?refactor:=20List=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EB=A1=9C=EC=A7=81=EC=9A=B8=20=EC=84=9C?= =?UTF-8?q?=EB=B9=84=EC=8A=A4=20=EB=A0=88=EC=9D=B4=EC=96=B4=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=20#99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - balanceContents만 받아서 RoomContent를 생성하는 것은 room.totalRound, balanceContents.size()가 동일한지 검증하지 않는다면 비즈니스 정책에 오류를 야기할 수 있으므로 해당 로직을 서비스 레이어로 이동함 --- .../ddangkong/domain/balance/room/RoomContent.java | 10 +--------- .../ddangkong/service/balance/room/RoomService.java | 9 ++++++++- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java index e70da730..d0e5cdd5 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java @@ -12,8 +12,6 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import java.time.LocalDateTime; -import java.util.List; -import java.util.stream.IntStream; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -43,13 +41,7 @@ public class RoomContent extends BaseEntity { @Column(nullable = false) private boolean isUsed; - public static List createRoomContents(Room room, List balanceContents) { - return IntStream.range(0, balanceContents.size()) - .mapToObj(index -> new RoomContent(room, balanceContents.get(index), index + 1)) - .toList(); - } - - private RoomContent(Room room, BalanceContent balanceContent, int round) { + public RoomContent(Room room, BalanceContent balanceContent, int round) { this.room = room; this.balanceContent = balanceContent; this.round = round; diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index 9482daca..731d78c1 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -19,6 +19,7 @@ import ddangkong.exception.InternalServerException; import java.util.Collections; import java.util.List; +import java.util.stream.IntStream; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -66,7 +67,7 @@ public void startGame(Long roomId) { // TODO Room에 카테고리 도입 후 수정 List balanceContents = findByRandom(Category.EXAMPLE, room.getTotalRound()); - List roomContents = RoomContent.createRoomContents(room, balanceContents); + List roomContents = createRoomContents(room, balanceContents); startRound(roomContents.get(0)); roomContentRepository.saveAll(roomContents); } @@ -81,6 +82,12 @@ private List findByRandom(Category category, int count) { return contents.subList(0, count); } + private List createRoomContents(Room room, List balanceContents) { + return IntStream.range(0, balanceContents.size()) + .mapToObj(index -> new RoomContent(room, balanceContents.get(index), index + 1)) + .toList(); + } + private void startRound(RoomContent roomContent) { // TODO #109 머지 시 반영 } From 269ffdcf642cd80c6382939917d2079c049c1e6e Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Tue, 6 Aug 2024 00:16:28 +0900 Subject: [PATCH 0560/1013] =?UTF-8?q?style:=20=EC=A3=BC=EC=84=9D=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20#126?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/test/java/ddangkong/domain/balance/room/RoomTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java index 9b0006ab..dc501958 100644 --- a/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java +++ b/backend/src/test/java/ddangkong/domain/balance/room/RoomTest.java @@ -181,7 +181,6 @@ class 라운드_종료 { class 방_초기화 { private static final int TOTAL_ROUND = 5; private static final int TIME_LIMIT = 30; - // private static final RoomStatus STATUS = RoomStatus.PROGRESS; private static final Category CATEGORY = Category.EXAMPLE; @Test From aa4ba348b50bc38138a1abf92b5b5969d966b63a Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Tue, 6 Aug 2024 00:21:59 +0900 Subject: [PATCH 0561/1013] =?UTF-8?q?refactor:=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=EB=AA=85=20=EB=B3=80=EA=B2=BD=20#126?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/ddangkong/domain/balance/room/RoomContent.java | 2 +- .../main/java/ddangkong/service/balance/room/RoomService.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java index 4643fe2a..de7a5feb 100644 --- a/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java +++ b/backend/src/main/java/ddangkong/domain/balance/room/RoomContent.java @@ -73,7 +73,7 @@ private void validateAlreadyUsed() { } } - public void updateUsed() { + public void finish() { isUsed = true; } diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index 91cfb8be..985a6dd4 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -96,7 +96,7 @@ public void resetRoom(Long roomId) { room.reset(); List roomContents = roomContentRepository.findAllByRoomAndIsUsed(room, false); for (RoomContent roomContent : roomContents) { - roomContent.updateUsed(); + roomContent.finish(); } if (room.getTotalRound() != roomContents.size()) { From 728222a46b86141fb641bf86512b0992ef8aeb40 Mon Sep 17 00:00:00 2001 From: leegwichan Date: Tue, 6 Aug 2024 00:29:42 +0900 Subject: [PATCH 0562/1013] =?UTF-8?q?fix:=20=ED=98=84=EC=9E=AC=20ERD?= =?UTF-8?q?=EC=97=90=20=EB=A7=9E=EA=B2=8C=20data-dev.sql=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/main/resources/sql/data-dev.sql | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/backend/src/main/resources/sql/data-dev.sql b/backend/src/main/resources/sql/data-dev.sql index a1b9416f..ba1d0179 100644 --- a/backend/src/main/resources/sql/data-dev.sql +++ b/backend/src/main/resources/sql/data-dev.sql @@ -20,15 +20,15 @@ VALUES ('민초', 1), INSERT INTO room(total_round, current_round, time_limit, status, category) -VALUES (5, 1, 30000, 'READY', 'EXAMPLE'); +VALUES (5, 1, 30000, 'PROGRESS', 'EXAMPLE'); -INSERT INTO room_content(room_id, balance_content_id, round, created_at, is_used) -VALUES (1, 1, 1, '2024-07-25 13:24:09', false), - (1, 2, 2, '2024-07-25 13:24:09', false), - (1, 3, 3, '2024-07-25 13:24:09', false), - (1, 4, 4, '2024-07-25 13:24:09', false), - (1, 5, 5, '2024-07-25 13:24:09', false); +INSERT INTO room_content(room_id, balance_content_id, round, round_ended_at, is_used) +VALUES (1, 1, 1, null, false), + (1, 2, 2, null, false), + (1, 3, 3, null, false), + (1, 4, 4, null, false), + (1, 5, 5, null, false); INSERT INTO member(room_id, nickname, is_master) From 88ddd7abe4a682a17639fa9a69d9b29fdad9dec6 Mon Sep 17 00:00:00 2001 From: leegwichan Date: Tue, 6 Aug 2024 00:30:34 +0900 Subject: [PATCH 0563/1013] =?UTF-8?q?test:=20data-dev.sql=EC=9D=B4=20?= =?UTF-8?q?=ED=98=84=EC=9E=AC=20ERD=EC=99=80=20=EC=9D=BC=EC=B9=98=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EC=BF=BC=EB=A6=AC=EC=9D=B8=EC=A7=80=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=ED=95=98=EB=8A=94=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ddangkong/infra/DevelopServerTest.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 backend/src/test/java/ddangkong/infra/DevelopServerTest.java diff --git a/backend/src/test/java/ddangkong/infra/DevelopServerTest.java b/backend/src/test/java/ddangkong/infra/DevelopServerTest.java new file mode 100644 index 00000000..54a86709 --- /dev/null +++ b/backend/src/test/java/ddangkong/infra/DevelopServerTest.java @@ -0,0 +1,15 @@ +package ddangkong.infra; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.test.context.jdbc.Sql; + +@SpringBootTest(webEnvironment = WebEnvironment.NONE) +class DevelopServerTest { + + @Test + @Sql(scripts = "/sql/data-dev.sql") + void dataSqlTest() { + } +} From 73a5eb112ee4b37188d5f3160c320cb4e67fce53 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Tue, 6 Aug 2024 09:55:15 +0900 Subject: [PATCH 0564/1013] =?UTF-8?q?refactor:=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EB=8C=80=EC=83=81=EC=97=90=20=EB=8C=80=ED=95=B4=20?= =?UTF-8?q?=EC=89=BD=EA=B2=8C=20=EC=9D=B4=ED=95=B4=ED=95=98=EA=B8=B0=20?= =?UTF-8?q?=EC=9C=84=ED=95=B4,=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=84=A4?= =?UTF-8?q?=EC=9D=B4=EB=B0=8D=20=EB=B3=80=EA=B2=BD=20#140?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/test/java/ddangkong/infra/DevelopServerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/test/java/ddangkong/infra/DevelopServerTest.java b/backend/src/test/java/ddangkong/infra/DevelopServerTest.java index 54a86709..d5ae5359 100644 --- a/backend/src/test/java/ddangkong/infra/DevelopServerTest.java +++ b/backend/src/test/java/ddangkong/infra/DevelopServerTest.java @@ -10,6 +10,6 @@ class DevelopServerTest { @Test @Sql(scripts = "/sql/data-dev.sql") - void dataSqlTest() { + void dataSqlInitTest() { } } From bc6302d429ece184c9210a5b8b8ae4e33f1b86fe Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Tue, 6 Aug 2024 13:07:14 +0900 Subject: [PATCH 0565/1013] =?UTF-8?q?style:=20RoomController=EC=9D=98=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=EB=A5=BC=20=EC=96=B4=ED=94=8C?= =?UTF-8?q?=EB=A6=AC=EC=BC=80=EC=9D=B4=EC=85=98=20=ED=9D=90=EB=A6=84=20?= =?UTF-8?q?=EC=88=9C=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20#142?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 각 테스트들도 흐름에 맞추어 변경 --- .../balance/room/RoomController.java | 12 +- .../balance/room/RoomControllerTest.java | 90 ++++++------ .../balance/room/RoomDocumentationTest.java | 136 +++++++++--------- 3 files changed, 120 insertions(+), 118 deletions(-) diff --git a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java index 24048d91..20e60443 100644 --- a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java +++ b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java @@ -53,6 +53,12 @@ public RoomJoinResponse joinRoom(@PathVariable @Positive Long roomId, @Valid @Re return roomService.joinRoom(request.nickname(), roomId); } + @ResponseStatus(HttpStatus.NO_CONTENT) + @PatchMapping("/balances/rooms/{roomId}/start") + public void startGame(@PathVariable @Positive Long roomId) { + roomService.startGame(roomId); + } + @ResponseStatus(HttpStatus.NO_CONTENT) @PatchMapping("/balances/rooms/{roomId}/next-round") public void moveToNextRound(@PathVariable @Positive Long roomId) { @@ -64,10 +70,4 @@ public RoundFinishedResponse getRoundFinished(@Positive @PathVariable Long roomI @Positive @RequestParam int round) { return roomService.getRoundFinished(roomId, round); } - - @ResponseStatus(HttpStatus.NO_CONTENT) - @PatchMapping("/balances/rooms/{roomId}/start") - public void startGame(@PathVariable @Positive Long roomId) { - roomService.startGame(roomId); - } } diff --git a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java index 4e3407c4..49f8f000 100644 --- a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java @@ -20,28 +20,6 @@ class RoomControllerTest extends BaseControllerTest { - @Nested - class 밸런스_게임_방_정보_조회 { - - @Test - void 게임_방_정보_조회() { - //when - RoomInfoResponse actual = RestAssured.given() - .when().get("/api/balances/rooms/1") - .then().contentType(ContentType.JSON).log().all() - .statusCode(200) - .extract().as(RoomInfoResponse.class); - - //then - assertAll( - () -> Assertions.assertThat(actual.members()).hasSize(4), - () -> Assertions.assertThat(actual.isGameStart()).isTrue(), - () -> Assertions.assertThat(actual.roomSetting().timeLimit()).isEqualTo(30000), - () -> Assertions.assertThat(actual.roomSetting().totalRound()).isEqualTo(5) - ); - } - } - @Nested class 방_생성 { @@ -82,6 +60,51 @@ class 방_생성 { } } + @Nested + class 밸런스_게임_방_정보_조회 { + + @Test + void 게임_방_정보_조회() { + //when + RoomInfoResponse actual = RestAssured.given() + .when().get("/api/balances/rooms/1") + .then().contentType(ContentType.JSON).log().all() + .statusCode(200) + .extract().as(RoomInfoResponse.class); + + //then + assertAll( + () -> Assertions.assertThat(actual.members()).hasSize(4), + () -> Assertions.assertThat(actual.isGameStart()).isTrue(), + () -> Assertions.assertThat(actual.roomSetting().timeLimit()).isEqualTo(30000), + () -> Assertions.assertThat(actual.roomSetting().totalRound()).isEqualTo(5) + ); + } + } + + @Nested + class 방_설정_변경 { + + @Test + void 방_설정_정보를_변경한다() { + // given + int totalRound = 5; + int timeLimit = 10000; + Category category = Category.EXAMPLE; + + RoomSettingRequest request = new RoomSettingRequest(totalRound, timeLimit, category); + + // when & then + RestAssured.given().log().all() + .contentType(ContentType.JSON) + .pathParam("roomId", 1L) + .body(request) + .when().patch("/api/balances/rooms/{roomId}") + .then().log().all() + .statusCode(HttpStatus.NO_CONTENT.value()); + } + } + @Nested class 방_참가 { @@ -170,29 +193,6 @@ class 다음_라운드_진행 { } } - @Nested - class 방_설정_변경 { - - @Test - void 방_설정_정보를_변경한다() { - // given - int totalRound = 5; - int timeLimit = 10000; - Category category = Category.EXAMPLE; - - RoomSettingRequest request = new RoomSettingRequest(totalRound, timeLimit, category); - - // when & then - RestAssured.given().log().all() - .contentType(ContentType.JSON) - .pathParam("roomId", 1L) - .body(request) - .when().patch("/api/balances/rooms/{roomId}") - .then().log().all() - .statusCode(HttpStatus.NO_CONTENT.value()); - } - } - @Nested class 라운드_종료_여부 { diff --git a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java index da5d57da..44db85ee 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java @@ -78,43 +78,7 @@ class 방_생성 { ) )); } - } - @Nested - class 방_참여 { - - private static final String ENDPOINT = "/api/balances/rooms/{roomId}/members"; - - @Test - void 방에_참여한다() throws Exception { - // given - RoomJoinResponse response = new RoomJoinResponse(1L, new MemberResponse(2L, "타콩", false)); - when(roomService.joinRoom(anyString(), anyLong())).thenReturn(response); - - RoomJoinRequest request = new RoomJoinRequest("타콩"); - String content = objectMapper.writeValueAsString(request); - - //when & then - mockMvc.perform(post(ENDPOINT, 1L) - .content(content) - .contentType(MediaType.APPLICATION_JSON) - ) - .andExpect(status().isCreated()) - .andDo(document("room/join", - pathParameters( - parameterWithName("roomId").description("참여방 ID") - ), - requestFields( - fieldWithPath("nickname").description("닉네임") - ), - responseFields( - fieldWithPath("roomId").type(NUMBER).description("생성된 방 ID"), - fieldWithPath("member.memberId").type(NUMBER).description("멤버 ID"), - fieldWithPath("member.nickname").type(STRING).description("멤버 닉네임"), - fieldWithPath("member.isMaster").type(BOOLEAN).description("방장 여부") - ) - )); - } } @Nested @@ -160,72 +124,110 @@ class 방_정보_조회 { } @Nested - class 게임_시작 { + class 방_설정_변경 { - private static final String ENDPOINT = "/api/balances/rooms/{roomId}/start"; + private static final String ENDPOINT = "/api/balances/rooms/{roomId}"; @Test - void 게임을_시작한다() throws Exception { + void 방의_설정_정보를_변경한다() throws Exception { // given - Long roomId = 1L; + int totalRound = 5; + int timeLimit = 30_000; + Category category = Category.EXAMPLE; + RoomSettingRequest content = new RoomSettingRequest(totalRound, timeLimit, category); - // when & then - mockMvc.perform(patch(ENDPOINT, roomId)) + // then + mockMvc.perform(patch(ENDPOINT, 1L) + .content(objectMapper.writeValueAsString(content)) + .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isNoContent()) - .andDo(document("room/start", + .andDo(document("room/setting", pathParameters( parameterWithName("roomId").description("방 ID") + ), + requestFields( + fieldWithPath("totalRound").type(NUMBER).description("변경할 총 라운드"), + fieldWithPath("timeLimit").type(NUMBER).description("변경할 제한 시간"), + fieldWithPath("category").type(STRING).description("변경할 카테고리") ) )); } } @Nested - class 다음_라운드로_이동 { + class 방_참여 { - private static final String ENDPOINT = "/api/balances/rooms/{roomId}/next-round"; + private static final String ENDPOINT = "/api/balances/rooms/{roomId}/members"; @Test - void 다음_라운드로_이동한다() throws Exception { - // when & then - mockMvc.perform(patch(ENDPOINT, 1L) + void 방에_참여한다() throws Exception { + // given + RoomJoinResponse response = new RoomJoinResponse(1L, new MemberResponse(2L, "타콩", false)); + when(roomService.joinRoom(anyString(), anyLong())).thenReturn(response); + + RoomJoinRequest request = new RoomJoinRequest("타콩"); + String content = objectMapper.writeValueAsString(request); + + //when & then + mockMvc.perform(post(ENDPOINT, 1L) + .content(content) .contentType(MediaType.APPLICATION_JSON) ) - .andExpect(status().isNoContent()) - .andDo(document("room/nextRound", + .andExpect(status().isCreated()) + .andDo(document("room/join", pathParameters( - parameterWithName("roomId").description("방 ID") + parameterWithName("roomId").description("참여방 ID") + ), + requestFields( + fieldWithPath("nickname").description("닉네임") + ), + responseFields( + fieldWithPath("roomId").type(NUMBER).description("생성된 방 ID"), + fieldWithPath("member.memberId").type(NUMBER).description("멤버 ID"), + fieldWithPath("member.nickname").type(STRING).description("멤버 닉네임"), + fieldWithPath("member.isMaster").type(BOOLEAN).description("방장 여부") ) )); } + } @Nested - class 방_설정_변경 { + class 게임_시작 { - private static final String ENDPOINT = "/api/balances/rooms/{roomId}"; + private static final String ENDPOINT = "/api/balances/rooms/{roomId}/start"; @Test - void 방의_설정_정보를_변경한다() throws Exception { + void 게임을_시작한다() throws Exception { // given - int totalRound = 5; - int timeLimit = 30_000; - Category category = Category.EXAMPLE; - RoomSettingRequest content = new RoomSettingRequest(totalRound, timeLimit, category); + Long roomId = 1L; - // then + // when & then + mockMvc.perform(patch(ENDPOINT, roomId)) + .andExpect(status().isNoContent()) + .andDo(document("room/start", + pathParameters( + parameterWithName("roomId").description("방 ID") + ) + )); + } + } + + @Nested + class 다음_라운드로_이동 { + + private static final String ENDPOINT = "/api/balances/rooms/{roomId}/next-round"; + + @Test + void 다음_라운드로_이동한다() throws Exception { + // when & then mockMvc.perform(patch(ENDPOINT, 1L) - .content(objectMapper.writeValueAsString(content)) - .contentType(MediaType.APPLICATION_JSON)) + .contentType(MediaType.APPLICATION_JSON) + ) .andExpect(status().isNoContent()) - .andDo(document("room/setting", + .andDo(document("room/nextRound", pathParameters( parameterWithName("roomId").description("방 ID") - ), - requestFields( - fieldWithPath("totalRound").type(NUMBER).description("변경할 총 라운드"), - fieldWithPath("timeLimit").type(NUMBER).description("변경할 제한 시간"), - fieldWithPath("category").type(STRING).description("변경할 카테고리") ) )); } From 766aa6a4fa626790653d44d3053b10d50496c29f Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Tue, 6 Aug 2024 13:08:30 +0900 Subject: [PATCH 0566/1013] =?UTF-8?q?docs:=20=EA=B2=8C=EC=9E=84=20?= =?UTF-8?q?=EC=8B=9C=EC=9E=91=20API=EB=A5=BC=20=EB=AC=B8=EC=84=9C=EC=97=90?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=20#142?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/docs/asciidoc/room.adoc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/backend/src/docs/asciidoc/room.adoc b/backend/src/docs/asciidoc/room.adoc index ff1ec84f..05c50738 100644 --- a/backend/src/docs/asciidoc/room.adoc +++ b/backend/src/docs/asciidoc/room.adoc @@ -82,6 +82,22 @@ response fields include::{snippets}/room/info/response-fields.adoc[] +=== 게임 시작 + +==== curl + +include::{snippets}/room/start/curl-request.adoc[] + +==== request + +include::{snippets}/room/start/http-request.adoc[] + +include::{snippets}/room/start/path-parameters.adoc[] + +==== response + +include::{snippets}/room/start/http-response.adoc[] + === 다음 라운드로 이동 ==== curl From 26acca88e9c726651a7b73a5457b3d5b7a8a999e Mon Sep 17 00:00:00 2001 From: novice0840 Date: Tue, 6 Aug 2024 13:55:16 +0900 Subject: [PATCH 0567/1013] =?UTF-8?q?fix:=20MOCK=20API=20BASE=5FURL=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#138?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/constants/url.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/src/constants/url.ts b/frontend/src/constants/url.ts index f9f7e02b..d68becc0 100644 --- a/frontend/src/constants/url.ts +++ b/frontend/src/constants/url.ts @@ -16,11 +16,11 @@ export const API_URL = { }; export const MOCK_API_URL = { - balanceContent: '/api/balances/rooms/:roomId/content', - vote: '/api/balances/rooms/:roomId/contents/:contentId/votes', - roundVoteResult: '/api/balances/rooms/:roomId/contents/:contentId/vote-result', - moveNextRound: '/api/balances/rooms/:roomId/contents', - finalResult: '/api/balances/rooms/:roomId/final', + balanceContent: `${BASE_URL}/api/balances/rooms/:roomId/content`, + vote: `${BASE_URL}/api/balances/rooms/:roomId/contents/:contentId/votes`, + roundVoteResult: `${BASE_URL}/api/balances/rooms/:roomId/contents/:contentId/vote-result`, + moveNextRound: `${BASE_URL}/api/balances/rooms/:roomId/contents`, + finalResult: `${BASE_URL}/api/balances/rooms/:roomId/final`, room: `${BASE_URL}/api/balances/rooms`, roomMembers: `${BASE_URL}/api/balances/rooms/:roomId`, roundVoteIsFinished: '/api/balances/rooms/:roomId/contents/:contentId/vote-finished', From e327a6c7c4b43fa46c190adc46da8d8cceafc3c7 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Tue, 6 Aug 2024 14:09:49 +0900 Subject: [PATCH 0568/1013] =?UTF-8?q?fix:=20MOCK=20API=20BASE=5FURL=20?= =?UTF-8?q?=EB=8B=A4=EC=8B=9C=20=EC=B6=94=EA=B0=80=20#138?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/constants/url.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/constants/url.ts b/frontend/src/constants/url.ts index d68becc0..b7281a1e 100644 --- a/frontend/src/constants/url.ts +++ b/frontend/src/constants/url.ts @@ -23,5 +23,5 @@ export const MOCK_API_URL = { finalResult: `${BASE_URL}/api/balances/rooms/:roomId/final`, room: `${BASE_URL}/api/balances/rooms`, roomMembers: `${BASE_URL}/api/balances/rooms/:roomId`, - roundVoteIsFinished: '/api/balances/rooms/:roomId/contents/:contentId/vote-finished', + roundVoteIsFinished: `${BASE_URL}/api/balances/rooms/:roomId/contents/:contentId/vote-finished`, }; From 185b181c2a165f7f361ab14f3708adaea73862af Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Tue, 6 Aug 2024 15:32:04 +0900 Subject: [PATCH 0569/1013] =?UTF-8?q?build:=20@sentry/react=20=EC=84=A4?= =?UTF-8?q?=EC=B9=98=20#137?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/package-lock.json | 130 +++++++++++++++++++++++++++++++++++++ frontend/package.json | 1 + 2 files changed, 131 insertions(+) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 6ddf923f..8de20d10 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -25,6 +25,7 @@ "@chromatic-com/storybook": "^1.6.1", "@emotion/babel-plugin": "^11.12.0", "@emotion/babel-preset-css-prop": "^11.11.0", + "@sentry/react": "^8.23.0", "@storybook/addon-essentials": "^8.2.2", "@storybook/addon-interactions": "^8.2.2", "@storybook/addon-links": "^8.2.2", @@ -3966,6 +3967,135 @@ "node": ">=14.0.0" } }, + "node_modules/@sentry-internal/browser-utils": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.23.0.tgz", + "integrity": "sha512-PQ0S7MRP8REo1iF+qZHNuLF+Qh7fuULA56tw0CRzTO1j7y87hQz9EJ8L0fBewuOitFQhSrZ7bfjJt9lIDTMfTQ==", + "dev": true, + "dependencies": { + "@sentry/core": "8.23.0", + "@sentry/types": "8.23.0", + "@sentry/utils": "8.23.0" + }, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/@sentry-internal/feedback": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.23.0.tgz", + "integrity": "sha512-xDwUohTOAW2Vwv9Vc6T2k8s8lvmQQck0YLmiafLbM2uqfyd2g3azRmWYQIsASSru2KdMYXgoLhZ/A0FGUlte9w==", + "dev": true, + "dependencies": { + "@sentry/core": "8.23.0", + "@sentry/types": "8.23.0", + "@sentry/utils": "8.23.0" + }, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/@sentry-internal/replay": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.23.0.tgz", + "integrity": "sha512-3HeLMgtJoQvX6FHw2kzo3vlLElMyNWLIaJl5BtUzVnQw1fEoV8R3Mwrn02nwW3IFIPUv0O+xn/Icx6InenfBqQ==", + "dev": true, + "dependencies": { + "@sentry-internal/browser-utils": "8.23.0", + "@sentry/core": "8.23.0", + "@sentry/types": "8.23.0", + "@sentry/utils": "8.23.0" + }, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/@sentry-internal/replay-canvas": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.23.0.tgz", + "integrity": "sha512-Guqy+Ae0ZdNNBFnkHFT6bbyzUcW/8liTUZUQS3fdHkaav4qKIPAdMGob2e09GKczf5zSaaobiChsMpaXMLHlMA==", + "dev": true, + "dependencies": { + "@sentry-internal/replay": "8.23.0", + "@sentry/core": "8.23.0", + "@sentry/types": "8.23.0", + "@sentry/utils": "8.23.0" + }, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/@sentry/browser": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.23.0.tgz", + "integrity": "sha512-KyoFp4et+y26wn99sXRp6+vme1Gha8DPQo2DbO64IR49tqkBXr8/D1QkpV3rqkPdttH7fefFNvaM4h3+9d6OtQ==", + "dev": true, + "dependencies": { + "@sentry-internal/browser-utils": "8.23.0", + "@sentry-internal/feedback": "8.23.0", + "@sentry-internal/replay": "8.23.0", + "@sentry-internal/replay-canvas": "8.23.0", + "@sentry/core": "8.23.0", + "@sentry/types": "8.23.0", + "@sentry/utils": "8.23.0" + }, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/@sentry/core": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.23.0.tgz", + "integrity": "sha512-o0tHpxwi5WxjaQPtY+BPkG8FliM4QB91QKoi2QclWvR9t9jUgMWZ4ikziybNiKICZRXtN9B6wSBWlPVWfsiN6A==", + "dev": true, + "dependencies": { + "@sentry/types": "8.23.0", + "@sentry/utils": "8.23.0" + }, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/@sentry/react": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@sentry/react/-/react-8.23.0.tgz", + "integrity": "sha512-Q+xuAySlQDvp0YWcxH4BtaDqA7On+ZvsZYcp0rFe1DE+e3/pyCqPae9dBCI+sQYPqnLgVoz05ANWorzSbpk08Q==", + "dev": true, + "dependencies": { + "@sentry/browser": "8.23.0", + "@sentry/core": "8.23.0", + "@sentry/types": "8.23.0", + "@sentry/utils": "8.23.0", + "hoist-non-react-statics": "^3.3.2" + }, + "engines": { + "node": ">=14.18" + }, + "peerDependencies": { + "react": "^16.14.0 || 17.x || 18.x || 19.x" + } + }, + "node_modules/@sentry/types": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.23.0.tgz", + "integrity": "sha512-oJbZ04chsz3Gqro3GJuAAcEsJ7RVjk3k4TvAMxmhN5tQUqwvKFtvWjfskcF75ECzY+8Qge6PI7eXoibkhjx8sg==", + "dev": true, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/@sentry/utils": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.23.0.tgz", + "integrity": "sha512-g+rkk+vFQnAz7xHGUTHXybA9qFdp1mtv3JGXtFKlLxPm8bKpzbBlJA3FiX4E7ai/Ksbv0N+K7c5fDth3LX3wAA==", + "dev": true, + "dependencies": { + "@sentry/types": "8.23.0" + }, + "engines": { + "node": ">=14.18" + } + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "dev": true, diff --git a/frontend/package.json b/frontend/package.json index 8597f6fb..afd5cfab 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -35,6 +35,7 @@ "@chromatic-com/storybook": "^1.6.1", "@emotion/babel-plugin": "^11.12.0", "@emotion/babel-preset-css-prop": "^11.11.0", + "@sentry/react": "^8.23.0", "@storybook/addon-essentials": "^8.2.2", "@storybook/addon-interactions": "^8.2.2", "@storybook/addon-links": "^8.2.2", From 47bd13d06cdebd2a48f8153530d527da1cc06646 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Tue, 6 Aug 2024 15:54:05 +0900 Subject: [PATCH 0570/1013] =?UTF-8?q?chore:=20storybook=20=EB=B0=B0?= =?UTF-8?q?=ED=8F=AC=20=EC=A3=BC=EC=86=8C=EB=A5=BC=20=EC=BD=94=EB=A9=98?= =?UTF-8?q?=ED=8A=B8=20=EB=8C=80=EC=8B=A0=20PR=20=EB=B3=B8=EB=AC=B8=20?= =?UTF-8?q?=ED=95=98=EB=8B=A8=EC=97=90=20=EC=9E=91=EC=84=B1=EB=90=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20#125?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/fe-cd-storybook.yml | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/.github/workflows/fe-cd-storybook.yml b/.github/workflows/fe-cd-storybook.yml index b4213823..37f082cc 100644 --- a/.github/workflows/fe-cd-storybook.yml +++ b/.github/workflows/fe-cd-storybook.yml @@ -45,9 +45,16 @@ jobs: with: github-token: ${{ secrets.TOKEN }} script: | - github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: '🎀 storybook 배포 주소 : https://woowacourse-teams.github.io/2024-ddangkong/storybook/' - }) + const pr = await github.pulls.get({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number + }); + const body = pr.data.body; + const newBody = body + "\n\n" + "## 🌸 Storybook 배포 주소 \n\n"+ "> https://woowacourse-teams.github.io/2024-ddangkong/storybook/"; + await github.pulls.update({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number, + body: newBody + }); From 6c5560b4396e6626a3a365d673a73712cd4bf045 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Tue, 6 Aug 2024 16:04:51 +0900 Subject: [PATCH 0571/1013] =?UTF-8?q?chore:=20storybook=20script=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20#125?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/fe-cd-storybook.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/fe-cd-storybook.yml b/.github/workflows/fe-cd-storybook.yml index 37f082cc..be770ec8 100644 --- a/.github/workflows/fe-cd-storybook.yml +++ b/.github/workflows/fe-cd-storybook.yml @@ -40,7 +40,7 @@ jobs: publish_dir: ./frontend/storybook-static destination_dir: storybook - - name: comment storybook url + - name: add storybook url in PR description uses: actions/github-script@v7 with: github-token: ${{ secrets.TOKEN }} @@ -48,7 +48,7 @@ jobs: const pr = await github.pulls.get({ owner: context.repo.owner, repo: context.repo.repo, - pull_number: context.issue.number + pull_number: context.payload.pull_request.number }); const body = pr.data.body; const newBody = body + "\n\n" + "## 🌸 Storybook 배포 주소 \n\n"+ "> https://woowacourse-teams.github.io/2024-ddangkong/storybook/"; From 371b4be059a82450998e603a0f9da1cdcae2df93 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Tue, 6 Aug 2024 16:16:07 +0900 Subject: [PATCH 0572/1013] =?UTF-8?q?chore:=20dev=20CD=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A6=BD=ED=8A=B8=EC=97=90=20ssl=20key=20=EC=84=B8?= =?UTF-8?q?=ED=8C=85=20=EC=8A=A4=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1=20#145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index bfce924b..3780fa23 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -27,6 +27,9 @@ jobs: run: | echo "${{ secrets.APPLICATION_DEV_YML }}" > ./src/main/resources/application-dev.yml + - name: Setting SSL/TLS Key + run: echo "${{ secrets.SSL_KEY }}" > ./src/main/resources/ssl/keystore.p12 + - name: Set up JDK 17 uses: actions/setup-java@v4 with: From 72c34b8f83c0d9b1d7715caccfac75e34f55e07b Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Tue, 6 Aug 2024 16:17:10 +0900 Subject: [PATCH 0573/1013] =?UTF-8?q?chore:=20Docker=20=EC=99=B8=EB=B6=80?= =?UTF-8?q?=20=ED=8F=AC=ED=8A=B8=20HTTP=20->=20HTTPS=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20#145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 3780fa23..7081020f 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -95,5 +95,5 @@ jobs: - name: Run new Docker container run: | - sudo nohup docker run -p 80:8080 --name $CONTAINER_NAME \ + sudo nohup docker run -p 443:8080 --name $CONTAINER_NAME \ $DOCKER_REPOSITORY_NAME:latest > ~/dev-nohup.out 2>&1 & From e63a0e5d1f5366a3b79718b75b4a48001d7e5dda Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Tue, 6 Aug 2024 16:23:01 +0900 Subject: [PATCH 0574/1013] =?UTF-8?q?chore:=20=EC=BD=94=EB=A9=98=ED=8A=B8?= =?UTF-8?q?=20=EC=8A=A4=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?#125?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/fe-cd-storybook.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/fe-cd-storybook.yml b/.github/workflows/fe-cd-storybook.yml index be770ec8..765f5fb9 100644 --- a/.github/workflows/fe-cd-storybook.yml +++ b/.github/workflows/fe-cd-storybook.yml @@ -45,14 +45,14 @@ jobs: with: github-token: ${{ secrets.TOKEN }} script: | - const pr = await github.pulls.get({ + const pr = await github.rest.pulls.get({ owner: context.repo.owner, repo: context.repo.repo, - pull_number: context.payload.pull_request.number + pull_number: context.issue.number }); const body = pr.data.body; const newBody = body + "\n\n" + "## 🌸 Storybook 배포 주소 \n\n"+ "> https://woowacourse-teams.github.io/2024-ddangkong/storybook/"; - await github.pulls.update({ + await github.rest.pulls.update({ owner: context.repo.owner, repo: context.repo.repo, pull_number: context.issue.number, From 71ba23e698712c2e1cfb8f0ca2b46f221955e23a Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Tue, 6 Aug 2024 16:45:39 +0900 Subject: [PATCH 0575/1013] =?UTF-8?q?chore:=20sslKey=ED=8C=8C=EC=9D=BC=20b?= =?UTF-8?q?ase64=20=EB=94=94=EC=BD=94=EB=94=A9=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 7081020f..5321ae3e 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -28,7 +28,7 @@ jobs: echo "${{ secrets.APPLICATION_DEV_YML }}" > ./src/main/resources/application-dev.yml - name: Setting SSL/TLS Key - run: echo "${{ secrets.SSL_KEY }}" > ./src/main/resources/ssl/keystore.p12 + run: echo "${{ secrets.SSL_KEY_BASE64 }}" | base64 -d > ./src/main/resources/ssl/keystore.p12 - name: Set up JDK 17 uses: actions/setup-java@v4 From 93cd759ab62f54a1eedce1027013cbb4cb771f79 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Tue, 6 Aug 2024 16:48:12 +0900 Subject: [PATCH 0576/1013] =?UTF-8?q?chore:=20ssl=20key=20=EB=94=94?= =?UTF-8?q?=EB=A0=89=ED=86=A0=EB=A6=AC=20=EC=B6=94=EA=B0=80=20=EB=AA=85?= =?UTF-8?q?=EB=A0=B9=20=EC=9E=90=EC=84=B1=20#145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 5321ae3e..efb0b375 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -28,7 +28,9 @@ jobs: echo "${{ secrets.APPLICATION_DEV_YML }}" > ./src/main/resources/application-dev.yml - name: Setting SSL/TLS Key - run: echo "${{ secrets.SSL_KEY_BASE64 }}" | base64 -d > ./src/main/resources/ssl/keystore.p12 + run: | + mkdir -p ./src/main/resources/ssl + echo "${{ secrets.SSL_KEY_BASE64 }}" | base64 -d > ./src/main/resources/ssl/keystore.p12 - name: Set up JDK 17 uses: actions/setup-java@v4 From 4a06ff2946514a719d0c9ea75a9a6faf46117560 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Tue, 6 Aug 2024 17:23:51 +0900 Subject: [PATCH 0577/1013] =?UTF-8?q?chore:=20SSL=20KEY=20pem=20=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=82=AC=EC=9A=A9=20#145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index efb0b375..b71cf679 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -30,7 +30,8 @@ jobs: - name: Setting SSL/TLS Key run: | mkdir -p ./src/main/resources/ssl - echo "${{ secrets.SSL_KEY_BASE64 }}" | base64 -d > ./src/main/resources/ssl/keystore.p12 + echo "${{ secrets.SSL_PUBLIC_KEY }}" > ./src/main/resources/ssl/publicKey.pem + echo "${{ secrets.SSL_PRIVATE_KEY }}" > ./src/main/resources/ssl/privateKey.pem - name: Set up JDK 17 uses: actions/setup-java@v4 @@ -67,6 +68,10 @@ jobs: CONTAINER_NAME: ddangkong-api-dev steps: + - name: Setting application-dev.yml + run: | + echo "${{ secrets.APPLICATION_DEV_YML }}" > ~/application-dev.yml + - name: Log in to Docker Hub uses: docker/login-action@v3 with: From 8988fe50479d66e7e069cf798c87313a3cf01d6b Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Tue, 6 Aug 2024 17:32:42 +0900 Subject: [PATCH 0578/1013] =?UTF-8?q?fix:=20cors=20allowedOrigin=20?= =?UTF-8?q?=EA=B0=92=20=ED=95=84=EB=93=9C=20=EC=A3=BC=EC=9E=85=20#145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/main/java/ddangkong/config/CorsConfig.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/backend/src/main/java/ddangkong/config/CorsConfig.java b/backend/src/main/java/ddangkong/config/CorsConfig.java index 2cbba1fa..0cec8bc5 100644 --- a/backend/src/main/java/ddangkong/config/CorsConfig.java +++ b/backend/src/main/java/ddangkong/config/CorsConfig.java @@ -1,6 +1,5 @@ package ddangkong.config; -import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.web.servlet.config.annotation.CorsRegistry; @@ -9,11 +8,7 @@ @Configuration public class CorsConfig implements WebMvcConfigurer { - private final String corsOrigin; - - public CorsConfig(@Value("${cors.origin}") String corsOrigin) { - this.corsOrigin = corsOrigin; - } + private final String corsOrigin = "*"; @Override public void addCorsMappings(CorsRegistry registry) { From f730aa5ad59c166b0a3aa3e196d368737ef60fb6 Mon Sep 17 00:00:00 2001 From: useon Date: Mon, 5 Aug 2024 21:42:14 +0900 Subject: [PATCH 0579/1013] =?UTF-8?q?design:=20=EC=B4=88=EB=8C=80=ED=95=98?= =?UTF-8?q?=EA=B8=B0=20=EB=AA=A8=EB=8B=AC=20UI=20=EA=B5=AC=ED=98=84=20#132?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/assets/images/copyIcon.png | Bin 0 -> 569 bytes .../common/InviteModal/InviteModal.styled.ts | 57 ++++++++++++++++++ .../common/InviteModal/InviteModal.tsx | 54 +++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 frontend/src/assets/images/copyIcon.png create mode 100644 frontend/src/components/common/InviteModal/InviteModal.styled.ts create mode 100644 frontend/src/components/common/InviteModal/InviteModal.tsx diff --git a/frontend/src/assets/images/copyIcon.png b/frontend/src/assets/images/copyIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..2d44a5231e377c29e7ff848c8fa58354c4b633a3 GIT binary patch literal 569 zcmV-90>=G`P)>lXf00009a7bBm000&x z000&x0ZCFM@Bjb+0drDELIAGL9O(c600d`2O+f$vv5yP0EN4^96|Cy;K?ZlDu5fhkNNouDv*Wdd;m*Z@0#DJK5s4Pa7?1JL^(V2!D1-{Wf2 z#4kA^7?6|0efQm9;R}Z}BHh89g7iibFyw_)G3kT!1WhcGOPa|O*LC4I4ooSE0`vL2 zJ$)qQ8n@$}R86PTiUZ&G+hks$iMo-CG)-G0nU0AYFw^VxU;?`l+qPkXELIt#d^cbs zw=63{U8uhwL4> zlrSSE?OU-{B0&&v?Mba)%gAoGGcC#=(J|sJmrJer;v7bvsaeH1BhrY9TlRz# zgk(Z{$T2aZ;+9M4goywb;sN!*ThY8)Q6(#l$K&*yYvt6XmK_&p+Q%*GM24hU`aWyo!FlxFTxr(+-dc5x&4i-#Y=KC_x~HFC_=$T9!ch}w`=s}(rN^L@7v(8NWv z6(mVgbwO?u@_$gb_!$g{!8<$`sJ~Vj;iLJk($PSGW=r`5c>&I=P$IQC00000NkvXX Hu0mjf{*?7Q literal 0 HcmV?d00001 diff --git a/frontend/src/components/common/InviteModal/InviteModal.styled.ts b/frontend/src/components/common/InviteModal/InviteModal.styled.ts new file mode 100644 index 00000000..a94dbdb8 --- /dev/null +++ b/frontend/src/components/common/InviteModal/InviteModal.styled.ts @@ -0,0 +1,57 @@ +import { css } from '@emotion/react'; + +import { Theme } from '@/styles/Theme'; + +export const inviteModalHeader = css` + display: flex; + position: relative; + justify-content: space-between; + align-items: center; +`; + +export const inviteModalTitle = css` + position: absolute; + left: 50%; + + font-size: 1.6rem; + text-align: center; + transform: translateX(-50%); +`; + +export const inviteModalIconButton = css` + margin-left: auto; +`; + +export const inviteModalUl = css` + display: flex; + flex-direction: column; + justify-content: center; +`; + +export const inviteModalLi = css` + display: flex; + justify-content: center; + align-items: center; + gap: 0.8rem; + padding: 0.8rem; + border-radius: ${Theme.borderRadius.radius10}; + + background-color: ${Theme.color.gray200}; +`; + +export const inviteModalLinkButton = css` + width: 100%; + padding: 2rem 1.2rem; + background: none; + border: none; + cursor: pointer; +`; + +export const inviteModalLinkButtonInfoWrapper = css` + display: flex; + justify-content: space-between; +`; + +export const inviteModalCopyIcon = css` + width: 10%; +`; diff --git a/frontend/src/components/common/InviteModal/InviteModal.tsx b/frontend/src/components/common/InviteModal/InviteModal.tsx new file mode 100644 index 00000000..7bec03c1 --- /dev/null +++ b/frontend/src/components/common/InviteModal/InviteModal.tsx @@ -0,0 +1,54 @@ +import { + inviteModalLi, + inviteModalHeader, + inviteModalIconButton, + inviteModalTitle, + inviteModalUl, + inviteModalLinkButton, + inviteModalLinkButtonInfoWrapper, + inviteModalCopyIcon, +} from './InviteModal.styled'; +import Modal from '../Modal/Modal'; + +import CopyIcon from '@/assets/images/copyIcon.png'; + +interface InviteModalProps { + isOpen: boolean; + onClose: () => void; +} + +const InviteModal = ({ isOpen, onClose }: InviteModalProps) => { + const handleCopy = () => { + // TODO: 링크 영역 클릭하면 카피되는 기능 + // TODO: 카피가 성공하면 토스트 복사 알림 + }; + + return ( + + + 초대하기 + + + +
        +
      • {/* TODO: P2에 QR 추가 */}
      • +
      • + +
      • +
      +
      + + + 닫기 + + +
      + ); +}; + +export default InviteModal; From 3e56b9c82b54bb8f0662aaaa5317aab10aefa327 Mon Sep 17 00:00:00 2001 From: useon Date: Mon, 5 Aug 2024 21:50:13 +0900 Subject: [PATCH 0580/1013] =?UTF-8?q?design:=20=ED=86=A0=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20UI=20=EA=B5=AC=ED=98=84=20#132?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/common/Toast/Toast.styled.ts | 43 +++++++++++++++++++ .../src/components/common/Toast/Toast.tsx | 34 +++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 frontend/src/components/common/Toast/Toast.styled.ts create mode 100644 frontend/src/components/common/Toast/Toast.tsx diff --git a/frontend/src/components/common/Toast/Toast.styled.ts b/frontend/src/components/common/Toast/Toast.styled.ts new file mode 100644 index 00000000..58d6e81b --- /dev/null +++ b/frontend/src/components/common/Toast/Toast.styled.ts @@ -0,0 +1,43 @@ +import { css, keyframes } from '@emotion/react'; + +import { Theme } from '@/styles/Theme'; + +export const toastLayout = (isVisible: boolean) => css` + position: fixed; + bottom: 4.4rem; + left: 50%; + padding: 1rem 2rem; + border-radius: ${Theme.borderRadius.radius20}; + + background-color: rgb(0 0 0 / 80%); + + color: white; + font-size: 1.2rem; + + animation: ${isVisible ? fadeIn : fadeOut} 0.5s ease forwards; + transform: translateX(-50%); + box-shadow: 0 0.2rem 0.4rem rgb(0 0 0 / 20%); + transition: opacity 0.3s ease-in-out; +`; + +const fadeIn = keyframes` + from { + opacity: 0; + transform: translateX(-50%) translateY(1rem); + } + to { + opacity: 1; + transform: translateX(-50%) translateY(0); + } +`; + +const fadeOut = keyframes` + from { + opacity: 1; + transform: translateX(-50%) translateY(0); + } + to { + opacity: 0; + transform: translateX(-50%) translateY(1rem); + } +`; diff --git a/frontend/src/components/common/Toast/Toast.tsx b/frontend/src/components/common/Toast/Toast.tsx new file mode 100644 index 00000000..387bd42e --- /dev/null +++ b/frontend/src/components/common/Toast/Toast.tsx @@ -0,0 +1,34 @@ +import { useEffect, useState } from 'react'; +import ReactDOM from 'react-dom'; + +import { toastLayout } from './Toast.styled'; + +interface ToastProps { + message: string; + duration?: number; + style?: React.CSSProperties; +} + +const Toast = ({ message, duration = 2000, style }: ToastProps) => { + const [isVisible, setIsVisible] = useState(false); + + useEffect(() => { + setIsVisible(true); + + const timer = setTimeout(() => { + setIsVisible(false); + }, duration); + + return () => clearTimeout(timer); + }, [duration]); + + const toastContent = ( +
      + {message} +
      + ); + + return ReactDOM.createPortal(toastContent, document.body); +}; + +export default Toast; From 15dcc0b38693e6441ab02f1641c266dcb827cd6f Mon Sep 17 00:00:00 2001 From: useon Date: Mon, 5 Aug 2024 21:55:28 +0900 Subject: [PATCH 0581/1013] =?UTF-8?q?feat:=20=EB=A7=81=ED=81=AC=EA=B0=80?= =?UTF-8?q?=20=EB=B3=B5=EC=82=AC=EB=90=98=EB=A9=B4=20=ED=86=A0=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EB=A1=9C=20=EC=95=8C=EB=A0=A4=EC=A3=BC=EB=8A=94=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20#132?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/common/InviteModal/InviteModal.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/common/InviteModal/InviteModal.tsx b/frontend/src/components/common/InviteModal/InviteModal.tsx index 7bec03c1..39e86a95 100644 --- a/frontend/src/components/common/InviteModal/InviteModal.tsx +++ b/frontend/src/components/common/InviteModal/InviteModal.tsx @@ -1,3 +1,5 @@ +import { useState } from 'react'; + import { inviteModalLi, inviteModalHeader, @@ -9,6 +11,7 @@ import { inviteModalCopyIcon, } from './InviteModal.styled'; import Modal from '../Modal/Modal'; +import Toast from '../Toast/Toast'; import CopyIcon from '@/assets/images/copyIcon.png'; @@ -18,9 +21,12 @@ interface InviteModalProps { } const InviteModal = ({ isOpen, onClose }: InviteModalProps) => { + const [isCopied, setIsCopied] = useState(false); + const handleCopy = () => { + setIsCopied(true); + setTimeout(() => setIsCopied(false), 2000); // TODO: 링크 영역 클릭하면 카피되는 기능 - // TODO: 카피가 성공하면 토스트 복사 알림 }; return ( @@ -47,6 +53,7 @@ const InviteModal = ({ isOpen, onClose }: InviteModalProps) => { 닫기 + {isCopied && } ); }; From 0a0bf6156b86c15e2f7dcea675ff847f425ddc3c Mon Sep 17 00:00:00 2001 From: useon Date: Mon, 5 Aug 2024 22:01:21 +0900 Subject: [PATCH 0582/1013] =?UTF-8?q?feat:=20=EC=B4=88=EB=8C=80=20?= =?UTF-8?q?=EB=A7=81=ED=81=AC=20=EC=98=81=EC=97=AD=EC=9D=84=20=ED=81=B4?= =?UTF-8?q?=EB=A6=AD=EC=8B=9C=20=EC=B4=88=EB=8C=80=20=EB=A7=81=ED=81=AC?= =?UTF-8?q?=EB=A5=BC=20=EB=B3=B5=EC=82=AC=ED=95=98=EB=8A=94=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20#132?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/common/InviteModal/InviteModal.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/common/InviteModal/InviteModal.tsx b/frontend/src/components/common/InviteModal/InviteModal.tsx index 39e86a95..b0d5bf32 100644 --- a/frontend/src/components/common/InviteModal/InviteModal.tsx +++ b/frontend/src/components/common/InviteModal/InviteModal.tsx @@ -23,10 +23,10 @@ interface InviteModalProps { const InviteModal = ({ isOpen, onClose }: InviteModalProps) => { const [isCopied, setIsCopied] = useState(false); - const handleCopy = () => { + const handleCopy = async () => { + await navigator.clipboard.writeText('복사되어야하는링크'); setIsCopied(true); setTimeout(() => setIsCopied(false), 2000); - // TODO: 링크 영역 클릭하면 카피되는 기능 }; return ( From 2c0f069a2b2d4d19b7d4ecb62c1c4a8224390a20 Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 6 Aug 2024 03:07:39 +0900 Subject: [PATCH 0583/1013] =?UTF-8?q?refactor:=20=EC=B4=88=EB=8C=80=20?= =?UTF-8?q?=EB=AA=A8=EB=8B=AC=EC=97=90=20=EC=B4=88=EB=8C=80=20=EB=A7=81?= =?UTF-8?q?=ED=81=AC=20prop=20=EC=B6=94=EA=B0=80=20#132?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/common/InviteModal/InviteModal.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/common/InviteModal/InviteModal.tsx b/frontend/src/components/common/InviteModal/InviteModal.tsx index b0d5bf32..7cbace71 100644 --- a/frontend/src/components/common/InviteModal/InviteModal.tsx +++ b/frontend/src/components/common/InviteModal/InviteModal.tsx @@ -18,13 +18,14 @@ import CopyIcon from '@/assets/images/copyIcon.png'; interface InviteModalProps { isOpen: boolean; onClose: () => void; + inviteUrl: string; } -const InviteModal = ({ isOpen, onClose }: InviteModalProps) => { +const InviteModal = ({ isOpen, onClose, inviteUrl }: InviteModalProps) => { const [isCopied, setIsCopied] = useState(false); const handleCopy = async () => { - await navigator.clipboard.writeText('복사되어야하는링크'); + await navigator.clipboard.writeText(inviteUrl); setIsCopied(true); setTimeout(() => setIsCopied(false), 2000); }; @@ -41,7 +42,7 @@ const InviteModal = ({ isOpen, onClose }: InviteModalProps) => {
    • From 7bf2b4e5be804e743c21759738be9af63b636f5d Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 6 Aug 2024 17:49:45 +0900 Subject: [PATCH 0584/1013] =?UTF-8?q?feat:=20=EB=8C=80=EA=B8=B0=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=EC=97=90=EC=84=9C=20=EC=B4=88=EB=8C=80?= =?UTF-8?q?=ED=95=98=EA=B8=B0=EB=A5=BC=20=EB=88=84=EB=A5=B4=EB=A9=B4=20?= =?UTF-8?q?=EC=B4=88=EB=8C=80=20=EB=A7=81=ED=81=AC=EA=B0=80=20=EB=8B=B4?= =?UTF-8?q?=EA=B8=B4=20=EC=B4=88=EB=8C=80=20=EB=AA=A8=EB=8B=AC=EC=9D=B4=20?= =?UTF-8?q?=EB=9C=A8=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20#132?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadyMembersContainer.tsx | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx index 8cc76c7a..fc977168 100644 --- a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx +++ b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx @@ -1,3 +1,6 @@ +import { useState } from 'react'; +import { useParams } from 'react-router-dom'; + import { readyMembersContainerLayout, totalNumber, @@ -8,6 +11,7 @@ import { membersContainer, inviteButton, } from './ReadyMembersContainer.styled'; +import InviteModal from '../common/InviteModal/InviteModal'; import crownIcon from '@/assets/images/crownIcon.png'; import plusIcon from '@/assets/images/plusIcon.png'; @@ -16,13 +20,25 @@ import { RoomMembers } from '@/types/room'; interface ReadyMembersContainerProps extends RoomMembers {} const ReadyMembersContainer = ({ members }: ReadyMembersContainerProps) => { + const [isModalOpen, setIsModalOpen] = useState(false); + const { roomId } = useParams(); + const inviteUrl = `${window.location.origin}${`/nickname/${roomId}`}`; + + const handleInviteButton = () => { + setIsModalOpen(true); + }; + + const handleModalClose = () => { + setIsModalOpen(false); + }; + return (

      총 인원 {members.length}명

      • -
      +
      ); }; From 97ba2776bc96b32782dd7aa77a13ebb692068d41 Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 6 Aug 2024 17:51:36 +0900 Subject: [PATCH 0585/1013] =?UTF-8?q?feat:=20=EC=B4=88=EB=8C=80=20?= =?UTF-8?q?=ED=95=98=EA=B8=B0=20=EB=AA=A8=EB=8B=AC=EC=97=90=20url=20prop?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EC=8A=A4=ED=83=80=EC=9D=BC?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20#132?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/common/InviteModal/InviteModal.styled.ts | 8 ++++++++ .../src/components/common/InviteModal/InviteModal.tsx | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/common/InviteModal/InviteModal.styled.ts b/frontend/src/components/common/InviteModal/InviteModal.styled.ts index a94dbdb8..552a90d7 100644 --- a/frontend/src/components/common/InviteModal/InviteModal.styled.ts +++ b/frontend/src/components/common/InviteModal/InviteModal.styled.ts @@ -52,6 +52,14 @@ export const inviteModalLinkButtonInfoWrapper = css` justify-content: space-between; `; +export const inviteModalUrlText = css` + overflow: hidden; + width: 95%; + + font-size: 1.2rem; + text-overflow: ellipsis; +`; + export const inviteModalCopyIcon = css` width: 10%; `; diff --git a/frontend/src/components/common/InviteModal/InviteModal.tsx b/frontend/src/components/common/InviteModal/InviteModal.tsx index 7cbace71..70060d58 100644 --- a/frontend/src/components/common/InviteModal/InviteModal.tsx +++ b/frontend/src/components/common/InviteModal/InviteModal.tsx @@ -9,6 +9,7 @@ import { inviteModalLinkButton, inviteModalLinkButtonInfoWrapper, inviteModalCopyIcon, + inviteModalUrlText, } from './InviteModal.styled'; import Modal from '../Modal/Modal'; import Toast from '../Toast/Toast'; @@ -42,7 +43,7 @@ const InviteModal = ({ isOpen, onClose, inviteUrl }: InviteModalProps) => {
    • From 98d0d533866fc4b30dfec2df2406e9e195eeab97 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Tue, 6 Aug 2024 18:01:59 +0900 Subject: [PATCH 0586/1013] =?UTF-8?q?build:=20discord=20alert=EC=9D=84=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20appender=20library=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?#144?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: leegwichan --- backend/build.gradle | 3 ++ backend/src/main/resources/logback-dev.xml | 48 ++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 backend/src/main/resources/logback-dev.xml diff --git a/backend/build.gradle b/backend/build.gradle index 302e6a58..3ba53984 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -23,6 +23,7 @@ configurations { repositories { mavenCentral() + maven { url 'https://jitpack.io' } } ext { @@ -47,6 +48,8 @@ dependencies { asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor:3.0.1' testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc:3.0.1' + // Discord Webhook Appender + implementation 'com.github.napstr:logback-discord-appender:1.0.0' } tasks.named('jar') { diff --git a/backend/src/main/resources/logback-dev.xml b/backend/src/main/resources/logback-dev.xml new file mode 100644 index 00000000..04bd1e9a --- /dev/null +++ b/backend/src/main/resources/logback-dev.xml @@ -0,0 +1,48 @@ + + + + + + + ${LOG_FILE} + + ${LOG_PATH}/ddangkong-%d{yyyy-MM-dd}.log + 14 + + + %d{yyyy-MM-dd HH:mm:ss,Asia/Seoul} [%thread] %-5level %logger{36} - %msg%n + + + + + + + ${DISCORD_WEBHOOK_URL} + + %d{yyyy-MM-dd HH:mm:ss,Asia/Seoul} [%thread] [%-5level] %logger{36} - %msg%n```%ex{full}``` + + + dev-error-alert-bot + + https://velog.velcdn.com/images/gwichanlee/post/dfdaead8-d98a-4d42-a975-2fb3edd7dde6/image.png + + false + + + + + + ERROR + + + + + + + + + + + + + From 0f5fc96fdec4e8475008b8e620b4e25b45a97957 Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 6 Aug 2024 18:08:43 +0900 Subject: [PATCH 0587/1013] =?UTF-8?q?test:=20=EC=B4=88=EB=8C=80=20?= =?UTF-8?q?=EB=AA=A8=EB=8B=AC=20=EC=8A=A4=ED=86=A0=EB=A6=AC=EB=B6=81=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1=20#132?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../InviteModal/InviteModal.stories.tsx | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 frontend/src/components/common/InviteModal/InviteModal.stories.tsx diff --git a/frontend/src/components/common/InviteModal/InviteModal.stories.tsx b/frontend/src/components/common/InviteModal/InviteModal.stories.tsx new file mode 100644 index 00000000..0db5d900 --- /dev/null +++ b/frontend/src/components/common/InviteModal/InviteModal.stories.tsx @@ -0,0 +1,46 @@ +import { StoryObj, Meta } from '@storybook/react'; +import { fn } from '@storybook/test'; + +import InviteModal from './InviteModal'; + +const meta = { + title: 'InviteModal', + component: InviteModal, + argTypes: { + isOpen: { + control: 'boolean', + default: true, + description: '모달이 열렸는지 여부를 나타냅니다.', + table: { + type: { + summary: 'boolean', + }, + }, + }, + onClose: { + description: '모달을 열고 닫기 위한 핸들러 함수입니다.', + }, + }, + args: { + onClose: fn(), + }, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const 초대_모달: Story = { + parameters: { + docs: { + description: { + story: '초대 모달', + }, + }, + }, + args: { + isOpen: true, + onClose: fn(), + inviteUrl: '링크입니다', + }, +}; From b21058b278cbcfa1d2e250c77d56f8a28a72c04c Mon Sep 17 00:00:00 2001 From: useon Date: Tue, 6 Aug 2024 19:18:56 +0900 Subject: [PATCH 0588/1013] =?UTF-8?q?test:=20=EB=8C=80=EA=B8=B0=EC=8B=A4?= =?UTF-8?q?=20=EB=A9=A4=EB=B2=84=20=EC=A0=95=EB=B3=B4=20msw=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0=20#132?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/mocks/handlers/index.ts | 3 ++- frontend/src/mocks/handlers/roomHandler.ts | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 frontend/src/mocks/handlers/roomHandler.ts diff --git a/frontend/src/mocks/handlers/index.ts b/frontend/src/mocks/handlers/index.ts index 05552ea8..c2ed13cc 100644 --- a/frontend/src/mocks/handlers/index.ts +++ b/frontend/src/mocks/handlers/index.ts @@ -1,4 +1,5 @@ import { contentHandler } from './balanceContentHandler'; +import { roomHandler } from './roomHandler'; import { voteHandler } from './voteHandler'; -export const handlers = [...contentHandler, ...voteHandler]; +export const handlers = [...contentHandler, ...voteHandler, ...roomHandler]; diff --git a/frontend/src/mocks/handlers/roomHandler.ts b/frontend/src/mocks/handlers/roomHandler.ts new file mode 100644 index 00000000..b2e5186f --- /dev/null +++ b/frontend/src/mocks/handlers/roomHandler.ts @@ -0,0 +1,11 @@ +import { http, HttpResponse } from 'msw'; + +import ROOM_INFO from '../data/roomInfo.json'; + +import { MOCK_API_URL } from '@/constants/url'; + +const getRoomMemberHandler = () => { + return HttpResponse.json(ROOM_INFO); +}; + +export const roomHandler = [http.get(MOCK_API_URL.roomMembers, getRoomMemberHandler)]; From 0d8d4a3f3cc5a693888e6a4805970d33535c9151 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Tue, 6 Aug 2024 20:04:56 +0900 Subject: [PATCH 0589/1013] =?UTF-8?q?chore:=20log=20=ED=8C=8C=EC=9D=BC=20b?= =?UTF-8?q?ind=20mount=20#144?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: leegwichan --- .github/workflows/be-cd-dev.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index bfce924b..277a1c9d 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -92,5 +92,6 @@ jobs: - name: Run new Docker container run: | - sudo nohup docker run -p 80:8080 --name $CONTAINER_NAME \ - $DOCKER_REPOSITORY_NAME:latest > ~/dev-nohup.out 2>&1 & + docker run -d -p 80:8080 --name $CONTAINER_NAME \ + -v /home/ubuntu/app-logs:/logs + $DOCKER_REPOSITORY_NAME:latest From 6733fe32ffd11a5e17cc2265cd78562968f05640 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Tue, 6 Aug 2024 20:15:27 +0900 Subject: [PATCH 0590/1013] =?UTF-8?q?chore:=20SSL=20=EC=9D=B8=EC=A6=9D?= =?UTF-8?q?=EC=84=9C=20=ED=86=B0=EC=BA=A3=EC=9D=B4=20=EC=9D=B8=EC=8B=9D=20?= =?UTF-8?q?=EA=B0=80=EB=8A=A5=ED=95=9C=20=ED=82=A4=20=EB=B0=A9=EC=8B=9D(p1?= =?UTF-8?q?2)=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20#145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index b71cf679..499b296f 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -30,8 +30,7 @@ jobs: - name: Setting SSL/TLS Key run: | mkdir -p ./src/main/resources/ssl - echo "${{ secrets.SSL_PUBLIC_KEY }}" > ./src/main/resources/ssl/publicKey.pem - echo "${{ secrets.SSL_PRIVATE_KEY }}" > ./src/main/resources/ssl/privateKey.pem + echo "${{ secrets.SSL_PUBLIC_KEY }}" > ./src/main/resources/ssl/keystore.p12 - name: Set up JDK 17 uses: actions/setup-java@v4 From f018d38cc842b1a3585967897f042c42e04754da Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Tue, 6 Aug 2024 21:29:24 +0900 Subject: [PATCH 0591/1013] =?UTF-8?q?chore:=20sslkey=EA=B0=92=20base64?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B8=EC=BD=94=EB=94=A9=20#145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 499b296f..7e3feda3 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -30,7 +30,7 @@ jobs: - name: Setting SSL/TLS Key run: | mkdir -p ./src/main/resources/ssl - echo "${{ secrets.SSL_PUBLIC_KEY }}" > ./src/main/resources/ssl/keystore.p12 + echo "${{ secrets.SSL_KEY_BASE64 }}" | base64 -d > ./src/main/resources/ssl/keystore.p12 - name: Set up JDK 17 uses: actions/setup-java@v4 From be7361b4ffbd3b3570b24c0d40d681a098445355 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Tue, 6 Aug 2024 22:09:52 +0900 Subject: [PATCH 0592/1013] =?UTF-8?q?feat:=20logging=20aop=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=20#144?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: leegwichan --- .../java/ddangkong/aop/logging/Polling.java | 11 +++ .../aop/logging/RequestLoggingAspect.java | 72 +++++++++++++++++++ .../balance/room/RoomController.java | 3 + .../balance/vote/BalanceVoteController.java | 2 + 4 files changed, 88 insertions(+) create mode 100644 backend/src/main/java/ddangkong/aop/logging/Polling.java create mode 100644 backend/src/main/java/ddangkong/aop/logging/RequestLoggingAspect.java diff --git a/backend/src/main/java/ddangkong/aop/logging/Polling.java b/backend/src/main/java/ddangkong/aop/logging/Polling.java new file mode 100644 index 00000000..c207eb10 --- /dev/null +++ b/backend/src/main/java/ddangkong/aop/logging/Polling.java @@ -0,0 +1,11 @@ +package ddangkong.aop.logging; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Polling { +} diff --git a/backend/src/main/java/ddangkong/aop/logging/RequestLoggingAspect.java b/backend/src/main/java/ddangkong/aop/logging/RequestLoggingAspect.java new file mode 100644 index 00000000..9a185529 --- /dev/null +++ b/backend/src/main/java/ddangkong/aop/logging/RequestLoggingAspect.java @@ -0,0 +1,72 @@ +package ddangkong.aop.logging; + +import static java.util.stream.Collectors.joining; + +import jakarta.servlet.http.HttpServletRequest; +import java.lang.reflect.Parameter; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +@Aspect +@Component +@Slf4j +public class RequestLoggingAspect { + + @Pointcut("execution(* ddangkong.controller..*Controller.*(..))") + public void allController() { + } + + @Pointcut("@annotation(ddangkong.aop.logging.Polling)") + public void polling() { + } + + @Pointcut("allController() && !polling()") + public void allControllerWithoutPolling() { + } + + @Before("allControllerWithoutPolling()") + public void logController(JoinPoint joinPoint) { + HttpServletRequest request = getHttpServletRequest(); + String uri = request.getRequestURI(); + String httpMethod = request.getMethod(); + String parameters = getParameters(request); + String body = getBody(joinPoint); + + log.info("Request Logging : {} {} body: {} parameters : {}", httpMethod, uri, body, parameters); + } + + private HttpServletRequest getHttpServletRequest() { + ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); + return requestAttributes.getRequest(); + } + + private String getParameters(HttpServletRequest request) { + return request.getParameterMap() + .entrySet() + .stream() + .map(entry -> "%s = %s".formatted(entry.getKey(), entry.getValue()[0])) + .collect(joining(", ")); + } + + private String getBody(JoinPoint joinPoint) { + MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); + Parameter[] parameters = methodSignature.getMethod().getParameters(); + Object[] args = joinPoint.getArgs(); + for (int i = 0; i < parameters.length; i++) { + Parameter param = parameters[i]; + Object arg = args[i]; + if (param.isAnnotationPresent(RequestBody.class)) { + return arg.toString(); + } + } + return null; + } +} diff --git a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java index 09b205f3..a8e99a77 100644 --- a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java +++ b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java @@ -1,5 +1,6 @@ package ddangkong.controller.balance.room; +import ddangkong.aop.logging.Polling; import ddangkong.controller.balance.room.dto.RoomInfoResponse; import ddangkong.controller.balance.room.dto.RoomJoinRequest; import ddangkong.controller.balance.room.dto.RoomJoinResponse; @@ -35,6 +36,7 @@ public RoomJoinResponse createRoom(@Valid @RequestBody RoomJoinRequest request) return roomService.createRoom(request.nickname()); } + @Polling @GetMapping("/balances/rooms/{roomId}") public RoomInfoResponse getBalanceGameRoomInfo(@Positive @PathVariable Long roomId) { return roomService.findRoomInfo(roomId); @@ -59,6 +61,7 @@ public void moveToNextRound(@PathVariable @Positive Long roomId) { roomService.moveToNextRound(roomId); } + @Polling @GetMapping("/balances/rooms/{roomId}/round-finished") public RoundFinishedResponse getRoundFinished(@Positive @PathVariable Long roomId, @Positive @RequestParam int round) { diff --git a/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java b/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java index daf119e7..b608743e 100644 --- a/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java +++ b/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java @@ -1,5 +1,6 @@ package ddangkong.controller.balance.vote; +import ddangkong.aop.logging.Polling; import ddangkong.controller.balance.vote.dto.BalanceVoteRequest; import ddangkong.controller.balance.vote.dto.BalanceVoteResponse; import ddangkong.controller.balance.vote.dto.BalanceVoteResultResponse; @@ -40,6 +41,7 @@ public BalanceVoteResponse createBalanceVote(@PathVariable @Positive Long roomId return balanceVoteService.createBalanceVote(request, roomId, contentId); } + @Polling @GetMapping("/balances/rooms/{roomId}/contents/{contentId}/vote-finished") public VoteFinishedResponse getAllVoteFinished(@PathVariable @Positive Long roomId, @PathVariable @Positive Long contentId) { From 5c8dd67e094befc5f01355b15f014211aac758b0 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Tue, 6 Aug 2024 22:17:02 +0900 Subject: [PATCH 0593/1013] feat: no resource found exception handling #144 Co-authored-by: leegwichan --- .../controller/exception/GlobalExceptionHandler.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java b/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java index 382fd267..9db91dea 100644 --- a/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java +++ b/backend/src/main/java/ddangkong/controller/exception/GlobalExceptionHandler.java @@ -9,12 +9,14 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.servlet.resource.NoResourceFoundException; @RestControllerAdvice @Slf4j public class GlobalExceptionHandler { private static final String SERVER_ERROR_MESSAGE = "서버 오류가 발생했습니다. 관리자에게 문의하세요."; + private static final String RESOURCE_NOT_FOUND_MESSAGE = "요청한 리소스를 찾을 수 없습니다."; @ExceptionHandler @ResponseStatus(HttpStatus.BAD_REQUEST) @@ -40,6 +42,14 @@ public ErrorResponse handleBadRequestException(BadRequestException e) { return new ErrorResponse(e.getMessage()); } + @ExceptionHandler + @ResponseStatus(HttpStatus.NOT_FOUND) + public ErrorResponse handleNoResourceFoundException(NoResourceFoundException e) { + log.warn(e.getMessage()); + + return new ErrorResponse(RESOURCE_NOT_FOUND_MESSAGE); + } + @ExceptionHandler @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public ErrorResponse handleInternalServerErrorException(InternalServerException e) { From 13c20e70aa4f9021c3c3190706c72031cb4e6865 Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Tue, 6 Aug 2024 22:29:46 +0900 Subject: [PATCH 0594/1013] =?UTF-8?q?feat:=20retention=20policy=20class?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20#144?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: leegwichan --- backend/src/main/java/ddangkong/aop/logging/Polling.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/ddangkong/aop/logging/Polling.java b/backend/src/main/java/ddangkong/aop/logging/Polling.java index c207eb10..ffd19713 100644 --- a/backend/src/main/java/ddangkong/aop/logging/Polling.java +++ b/backend/src/main/java/ddangkong/aop/logging/Polling.java @@ -6,6 +6,6 @@ import java.lang.annotation.Target; @Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) +@Retention(RetentionPolicy.CLASS) public @interface Polling { } From 75aea12c2a9e6a00885400bf01efa05f4bca6502 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Wed, 7 Aug 2024 00:30:50 +0900 Subject: [PATCH 0595/1013] =?UTF-8?q?feat:=20=EA=B2=8C=EC=9E=84=20?= =?UTF-8?q?=EC=8B=9C=EC=9E=91=20API=20=EC=97=B0=EB=8F=99=20#146?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/room.ts | 19 +++++++------------ frontend/src/constants/url.ts | 1 + frontend/src/pages/ReadyPage/useGameStart.ts | 11 +++++++++-- .../src/pages/ReadyPage/useGetRoomInfo.ts | 10 +++++++++- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/frontend/src/apis/room.ts b/frontend/src/apis/room.ts index bd6b2edd..540ec1a1 100644 --- a/frontend/src/apis/room.ts +++ b/frontend/src/apis/room.ts @@ -15,10 +15,6 @@ export const createRoom = async (nickname: string): Promise => }, }); - if (!res.ok) { - throw new Error('방 생성에 실패하였습니다'); - } - const data = await res.json(); return data; @@ -36,10 +32,6 @@ export const enterRoom = async (roomId: number, nickname: string): Promise => { url: API_URL.getRoomInfo(roomId), }); - if (!res.ok) { - throw new Error('방 정보 가져오기에 실패하였습니다'); - } - const data = await res.json(); return data; }; + +// 게임 시작 +export const startGame = async (roomId: number): Promise => { + fetcher.patch({ + url: API_URL.startGame(roomId), + }); +}; diff --git a/frontend/src/constants/url.ts b/frontend/src/constants/url.ts index b7281a1e..0b664082 100644 --- a/frontend/src/constants/url.ts +++ b/frontend/src/constants/url.ts @@ -11,6 +11,7 @@ export const API_URL = { room: `${BASE_URL}/api/balances/rooms`, enterRoom: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/members`, getRoomInfo: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}`, + startGame: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/start`, roundVoteIsFinished: (roomId: number, contentId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/contents/${contentId}/vote-finished`, }; diff --git a/frontend/src/pages/ReadyPage/useGameStart.ts b/frontend/src/pages/ReadyPage/useGameStart.ts index cbf6852f..6944a696 100644 --- a/frontend/src/pages/ReadyPage/useGameStart.ts +++ b/frontend/src/pages/ReadyPage/useGameStart.ts @@ -1,14 +1,21 @@ +import { useMutation } from '@tanstack/react-query'; +import { useParams } from 'react-router-dom'; import { useRecoilValue } from 'recoil'; +import { startGame } from '@/apis/room'; import { memberInfoState } from '@/recoil/atom'; export const useGameStart = () => { const memberInfo = useRecoilValue(memberInfoState); + const { roomId } = useParams(); + + const startGameMutate = useMutation({ + mutationFn: () => startGame(Number(roomId)), + }); const handleGameStart = () => { if (memberInfo.isMaster) { - // TODO: 게임 시작 API 연결 예정 - alert('Game Start'); + startGameMutate.mutate(); } }; diff --git a/frontend/src/pages/ReadyPage/useGetRoomInfo.ts b/frontend/src/pages/ReadyPage/useGetRoomInfo.ts index 2676a9a9..f3b118bd 100644 --- a/frontend/src/pages/ReadyPage/useGetRoomInfo.ts +++ b/frontend/src/pages/ReadyPage/useGetRoomInfo.ts @@ -1,11 +1,13 @@ import { useQuery } from '@tanstack/react-query'; -import { useParams } from 'react-router-dom'; +import { useEffect } from 'react'; +import { useNavigate, useParams } from 'react-router-dom'; import { getRoomInfo } from '@/apis/room'; import { QUERY_KEYS } from '@/constants/queryKeys'; export const useGetRoomInfo = () => { const { roomId } = useParams(); + const navigate = useNavigate(); const { data, isLoading, isError } = useQuery({ queryKey: [QUERY_KEYS.roomMembers, Number(roomId)], @@ -13,5 +15,11 @@ export const useGetRoomInfo = () => { refetchInterval: 1000, }); + useEffect(() => { + if (data?.isGameStart) { + navigate(`/${roomId}/game`); + } + }, [data?.isGameStart, roomId, navigate]); + return { data, isLoading, isError }; }; From 0e73c3eba1a4c0f2c84f3ecb1d2d69ba80157575 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Wed, 7 Aug 2024 00:37:20 +0900 Subject: [PATCH 0596/1013] =?UTF-8?q?fix:=20nickname=20=EC=83=81=EC=88=98?= =?UTF-8?q?=20=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD=20#146?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/NicknamePage/useMakeOrEnterRoom.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/NicknamePage/useMakeOrEnterRoom.ts b/frontend/src/pages/NicknamePage/useMakeOrEnterRoom.ts index c56862a9..1ebc9aa2 100644 --- a/frontend/src/pages/NicknamePage/useMakeOrEnterRoom.ts +++ b/frontend/src/pages/NicknamePage/useMakeOrEnterRoom.ts @@ -14,7 +14,6 @@ export const useMakeOrEnterRoom = () => { const navigate = useNavigate(); const { isMaster } = useRecoilValue(memberInfoState); const { roomId } = useParams(); - const nickname = nicknameInputRef.current?.value || randomNickname; const createRoomMutation = useMutation({ mutationFn: createRoom, @@ -37,6 +36,7 @@ export const useMakeOrEnterRoom = () => { }); const handleMakeOrEnterRoom = () => { + const nickname = nicknameInputRef.current?.value || randomNickname; if (isMaster) { createRoomMutation.mutate(nickname); } else { From c2f19a3e85017ce6c6de1751cea9160507f77cb7 Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 01:32:25 +0900 Subject: [PATCH 0597/1013] =?UTF-8?q?design:=20=EC=B4=88=EB=8C=80=20?= =?UTF-8?q?=EB=AA=A8=EB=8B=AC=20=EB=B0=B0=EA=B2=BD=20=EC=83=89=EC=83=81=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20#132?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/common/InviteModal/InviteModal.styled.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/common/InviteModal/InviteModal.styled.ts b/frontend/src/components/common/InviteModal/InviteModal.styled.ts index 552a90d7..606dfa96 100644 --- a/frontend/src/components/common/InviteModal/InviteModal.styled.ts +++ b/frontend/src/components/common/InviteModal/InviteModal.styled.ts @@ -2,6 +2,10 @@ import { css } from '@emotion/react'; import { Theme } from '@/styles/Theme'; +export const inviteModal = css` + background-color: ${Theme.color.peanut300}; +`; + export const inviteModalHeader = css` display: flex; position: relative; @@ -36,12 +40,12 @@ export const inviteModalLi = css` padding: 0.8rem; border-radius: ${Theme.borderRadius.radius10}; - background-color: ${Theme.color.gray200}; + background-color: #fff; `; export const inviteModalLinkButton = css` width: 100%; - padding: 2rem 1.2rem; + padding: 1.6rem 0.4rem; background: none; border: none; cursor: pointer; From 5d7fb66070f460a3c5b4f88b4a93e78481f296c2 Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 01:40:39 +0900 Subject: [PATCH 0598/1013] =?UTF-8?q?refactor:=20useClipBoard=20=EC=BB=A4?= =?UTF-8?q?=EC=8A=A4=ED=85=80=20=ED=9B=85=20=EC=83=9D=EC=84=B1=20#132?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/common/InviteModal/InviteModal.tsx | 14 ++++++-------- .../common/InviteModal/useClipBoard.tsx | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 frontend/src/components/common/InviteModal/useClipBoard.tsx diff --git a/frontend/src/components/common/InviteModal/InviteModal.tsx b/frontend/src/components/common/InviteModal/InviteModal.tsx index 70060d58..3cf07aef 100644 --- a/frontend/src/components/common/InviteModal/InviteModal.tsx +++ b/frontend/src/components/common/InviteModal/InviteModal.tsx @@ -1,5 +1,3 @@ -import { useState } from 'react'; - import { inviteModalLi, inviteModalHeader, @@ -10,7 +8,9 @@ import { inviteModalLinkButtonInfoWrapper, inviteModalCopyIcon, inviteModalUrlText, + inviteModal, } from './InviteModal.styled'; +import useClipBoard from './useClipBoard'; import Modal from '../Modal/Modal'; import Toast from '../Toast/Toast'; @@ -23,16 +23,14 @@ interface InviteModalProps { } const InviteModal = ({ isOpen, onClose, inviteUrl }: InviteModalProps) => { - const [isCopied, setIsCopied] = useState(false); + const { isCopied, copyToClipboard } = useClipBoard(); - const handleCopy = async () => { - await navigator.clipboard.writeText(inviteUrl); - setIsCopied(true); - setTimeout(() => setIsCopied(false), 2000); + const handleCopy = () => { + copyToClipboard(inviteUrl); }; return ( - + 초대하기 diff --git a/frontend/src/components/common/InviteModal/useClipBoard.tsx b/frontend/src/components/common/InviteModal/useClipBoard.tsx new file mode 100644 index 00000000..d2fba4b5 --- /dev/null +++ b/frontend/src/components/common/InviteModal/useClipBoard.tsx @@ -0,0 +1,15 @@ +import { useState } from 'react'; + +const useClipBoard = () => { + const [isCopied, setIsCopied] = useState(false); + + const copyToClipboard = async (text: string) => { + await navigator.clipboard.writeText(text); + setIsCopied(true); + setTimeout(() => setIsCopied(false), 2000); + }; + + return { isCopied, copyToClipboard }; +}; + +export default useClipBoard; From cfd73044eb19d3905a9592ee63988fc1fba1f1a7 Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 01:42:07 +0900 Subject: [PATCH 0599/1013] =?UTF-8?q?refactor:=20mock=20api=20url=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20#132?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/constants/url.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/src/constants/url.ts b/frontend/src/constants/url.ts index f9f7e02b..b7281a1e 100644 --- a/frontend/src/constants/url.ts +++ b/frontend/src/constants/url.ts @@ -16,12 +16,12 @@ export const API_URL = { }; export const MOCK_API_URL = { - balanceContent: '/api/balances/rooms/:roomId/content', - vote: '/api/balances/rooms/:roomId/contents/:contentId/votes', - roundVoteResult: '/api/balances/rooms/:roomId/contents/:contentId/vote-result', - moveNextRound: '/api/balances/rooms/:roomId/contents', - finalResult: '/api/balances/rooms/:roomId/final', + balanceContent: `${BASE_URL}/api/balances/rooms/:roomId/content`, + vote: `${BASE_URL}/api/balances/rooms/:roomId/contents/:contentId/votes`, + roundVoteResult: `${BASE_URL}/api/balances/rooms/:roomId/contents/:contentId/vote-result`, + moveNextRound: `${BASE_URL}/api/balances/rooms/:roomId/contents`, + finalResult: `${BASE_URL}/api/balances/rooms/:roomId/final`, room: `${BASE_URL}/api/balances/rooms`, roomMembers: `${BASE_URL}/api/balances/rooms/:roomId`, - roundVoteIsFinished: '/api/balances/rooms/:roomId/contents/:contentId/vote-finished', + roundVoteIsFinished: `${BASE_URL}/api/balances/rooms/:roomId/contents/:contentId/vote-finished`, }; From 8172dc71e72ca20aef700d072253c5cc2d8a617e Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 01:54:46 +0900 Subject: [PATCH 0600/1013] =?UTF-8?q?chore:=20jest=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EB=AF=B8=EB=94=94=EC=96=B4=20=ED=8C=8C=EC=9D=BC=20=EB=AA=A8?= =?UTF-8?q?=ED=82=B9=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0=EC=9D=84=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20jest=20config=EC=97=90=EC=84=9C=20transfor?= =?UTF-8?q?m=20=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20babel?= =?UTF-8?q?-jest=20=EC=84=A4=EC=B9=98=20#132?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/jest.config.json | 4 ++++ frontend/package-lock.json | 4 +++- frontend/package.json | 1 + frontend/src/mocks/fileMock.js | 9 +++++++++ 4 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 frontend/src/mocks/fileMock.js diff --git a/frontend/jest.config.json b/frontend/jest.config.json index 8d9842c2..4b36e3d1 100644 --- a/frontend/jest.config.json +++ b/frontend/jest.config.json @@ -8,6 +8,10 @@ "^@/test-utils": "/src/utils/test-utils", "^@/(.*)$": "/src/$1" }, + "transform": { + "\\.[jt]sx?$": "babel-jest", + "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/src/mocks/fileMock.js" + }, "setupFiles": ["./jest.polyfills.js"], "setupFilesAfterEnv": ["/jest.setup.ts"], "clearMocks": true diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 6ddf923f..ad5303b9 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -43,6 +43,7 @@ "@types/react-dom": "^18.3.0", "@typescript-eslint/eslint-plugin": "^7.16.0", "@typescript-eslint/parser": "^7.16.0", + "babel-jest": "^29.7.0", "babel-loader": "^9.1.3", "core-js": "^3.37.1", "dotenv": "^16.4.5", @@ -7114,8 +7115,9 @@ }, "node_modules/babel-jest": { "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, - "license": "MIT", "dependencies": { "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", diff --git a/frontend/package.json b/frontend/package.json index 8597f6fb..756089cd 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -53,6 +53,7 @@ "@types/react-dom": "^18.3.0", "@typescript-eslint/eslint-plugin": "^7.16.0", "@typescript-eslint/parser": "^7.16.0", + "babel-jest": "^29.7.0", "babel-loader": "^9.1.3", "core-js": "^3.37.1", "dotenv": "^16.4.5", diff --git a/frontend/src/mocks/fileMock.js b/frontend/src/mocks/fileMock.js new file mode 100644 index 00000000..3ea1ef26 --- /dev/null +++ b/frontend/src/mocks/fileMock.js @@ -0,0 +1,9 @@ +const path = require('path'); + +module.exports = { + process(sourceText, sourcePath, options) { + return { + code: `module.exports = ${JSON.stringify(path.basename(sourcePath))};`, + }; + }, +}; From b54d518a6d1a08324a52a0011ba3fe2c31edb6fb Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Tue, 6 Aug 2024 15:33:23 +0900 Subject: [PATCH 0601/1013] =?UTF-8?q?chore:=20Sentry=20=EC=B4=88=EA=B8=B0?= =?UTF-8?q?=20=EC=84=A4=EC=A0=95=20#137?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/index.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index ebbb031e..a8ff6243 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -1,4 +1,5 @@ import { Global, ThemeProvider } from '@emotion/react'; +import * as Sentry from '@sentry/react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import ReactDOM from 'react-dom/client'; import { RecoilRoot } from 'recoil'; @@ -7,6 +8,12 @@ import App from './App'; import GlobalStyle from './styles/GlobalStyle'; import { Theme } from './styles/Theme'; +Sentry.init({ + dsn: process.env.SENTRY_DSN, + integrations: [Sentry.browserTracingIntegration()], + enableTracing: true, // tracesSampleRate와 tracesSampler 기본값 설정 +}); + const queryClient = new QueryClient(); const enableMocking = async () => { From 151f7198ef84b592f785f03c7344d08b65c78a1e Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 14:38:01 +0900 Subject: [PATCH 0602/1013] =?UTF-8?q?refactor:=20url=20=ED=8C=8C=EB=9D=BC?= =?UTF-8?q?=EB=AF=B8=ED=84=B0=20=EB=A1=9C=EC=A7=81=20useParams=EB=A5=BC=20?= =?UTF-8?q?=EC=9D=B4=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20game=20=ED=8E=98=EC=9D=B4=EC=A7=80=20ro?= =?UTF-8?q?uter=EA=B0=80=20roomId=20=EC=9D=B8=EC=9E=90=EB=A5=BC=20?= =?UTF-8?q?=EB=B0=9B=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=EB=90=A8?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=9D=BC=20=EA=B4=80=EB=A0=A8=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/NextRoundButton/NextRoundButton.tsx | 9 ++++----- frontend/src/hooks/useMyGameStatus.ts | 14 ++++++++------ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx index ce453cbc..22736f75 100644 --- a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx +++ b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx @@ -1,4 +1,4 @@ -import { useLocation, useNavigate } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router-dom'; import { useRecoilValue } from 'recoil'; import useMoveNextRoundMutation from './NextRoundButton.hook'; @@ -10,11 +10,10 @@ import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; import { memberInfoState } from '@/recoil/atom'; const NextRoundButton = () => { - const { search } = useLocation(); - const roomId = Number(new URLSearchParams(search).get('roomId')); + const { roomId } = useParams(); const navigate = useNavigate(); const { balanceContent } = useBalanceContentQuery(); - const { mutateAsync: moveNextRound } = useMoveNextRoundMutation(roomId); + const { mutateAsync: moveNextRound } = useMoveNextRoundMutation(Number(roomId)); const memberInfo = useRecoilValue(memberInfoState); const isLastRound = balanceContent?.currentRound === balanceContent?.totalRound; @@ -26,7 +25,7 @@ const NextRoundButton = () => { const goToNextRound = async () => { await moveNextRound(); - navigate(ROUTES.game, { replace: true }); + navigate(ROUTES.game(Number(roomId)), { replace: true }); }; return ( diff --git a/frontend/src/hooks/useMyGameStatus.ts b/frontend/src/hooks/useMyGameStatus.ts index 81259097..1ab13eb3 100644 --- a/frontend/src/hooks/useMyGameStatus.ts +++ b/frontend/src/hooks/useMyGameStatus.ts @@ -1,5 +1,5 @@ import { useEffect } from 'react'; -import { useLocation, useNavigate } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router-dom'; import useBalanceContentQuery from './useBalanceContentQuery'; import useMyGameStatusQuery from './useMyGameStatusQuery'; @@ -8,25 +8,27 @@ import useRoundVoteResultQuery from './useRoundVoteResultQuery'; import { ROUTES } from '@/constants/routes'; const useMyGameStatus = () => { - const { search } = useLocation(); - const roomId = Number(new URLSearchParams(search).get('roomId')); + const { roomId } = useParams(); const navigate = useNavigate(); const { balanceContent } = useBalanceContentQuery(); const { groupRoundResult, totalResult } = useRoundVoteResultQuery({ - roomId: roomId, + roomId: Number(roomId), contentId: balanceContent?.contentId, }); - const { isRoundFinished, isGameFinished } = useMyGameStatusQuery({ balanceContent, roomId }); + const { isRoundFinished, isGameFinished } = useMyGameStatusQuery({ + roomId: Number(roomId), + balanceContent, + }); const goToGameResult = () => { navigate(ROUTES.gameResult); }; const goToNextRound = async () => { - navigate(ROUTES.game); + navigate(ROUTES.game(Number(roomId))); }; useEffect(() => { From 39c0cd1657c1c37442d2c54d7b52eb53eab47402 Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 14:50:33 +0900 Subject: [PATCH 0603/1013] =?UTF-8?q?refactor:=20=EB=B0=A9=EC=9E=A5?= =?UTF-8?q?=EB=A7=8C=20=EA=B2=B0=EA=B3=BC=20=ED=99=95=EC=9D=B8=20=EB=98=90?= =?UTF-8?q?=EB=8A=94=20=EB=8B=A4=EC=9D=8C=20=EB=B2=84=ED=8A=BC=EC=9D=B4=20?= =?UTF-8?q?=ED=99=9C=EC=84=B1=ED=99=94=20=EB=90=A8=EC=9D=84=20=EB=AA=85?= =?UTF-8?q?=EC=8B=9C=EC=A0=81=EC=9C=BC=EB=A1=9C=20=EB=B3=B4=EC=97=AC?= =?UTF-8?q?=EC=A3=BC=EA=B8=B0=20=EC=9C=84=ED=95=B4=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/common/NextRoundButton/NextRoundButton.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx index 22736f75..9817d8fb 100644 --- a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx +++ b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx @@ -17,7 +17,6 @@ const NextRoundButton = () => { const memberInfo = useRecoilValue(memberInfoState); const isLastRound = balanceContent?.currentRound === balanceContent?.totalRound; - const isButtonDisabled = !memberInfo.isMaster; const goToGameResult = () => { navigate(ROUTES.gameResult, { replace: true }); @@ -34,7 +33,7 @@ const NextRoundButton = () => { style={{ width: '100%' }} text={isLastRound ? '결과 확인' : '다음'} onClick={isLastRound ? goToGameResult : goToNextRound} - disabled={isButtonDisabled} + disabled={!memberInfo.isMaster} />
    ); From e89d002ab028ab5161aed3a9135afced691f76e8 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Wed, 7 Aug 2024 14:54:13 +0900 Subject: [PATCH 0604/1013] =?UTF-8?q?refactor:=20hook=20=EB=B0=98=ED=99=98?= =?UTF-8?q?=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EB=B3=80=EA=B2=BD=20#146?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/ReadyPage/ReadyPage.tsx | 4 ++-- frontend/src/pages/ReadyPage/useGetRoomInfo.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/pages/ReadyPage/ReadyPage.tsx b/frontend/src/pages/ReadyPage/ReadyPage.tsx index a08cb95f..cc6d8a3a 100644 --- a/frontend/src/pages/ReadyPage/ReadyPage.tsx +++ b/frontend/src/pages/ReadyPage/ReadyPage.tsx @@ -7,7 +7,7 @@ import Button from '@/components/common/Button/Button'; import ReadyMembersContainer from '@/components/ReadyMembersContainer/ReadyMembersContainer'; const ReadyPage = () => { - const { data, isLoading, isError } = useGetRoomInfo(); + const { members, isLoading, isError } = useGetRoomInfo(); const { isMaster, handleGameStart } = useGameStart(); return ( @@ -15,7 +15,7 @@ const ReadyPage = () => { {isError &&
    에러 발생
    } {isLoading &&
    로딩중.......
    } - {data && } + {members && }
  • ); diff --git a/frontend/src/pages/ReadyPage/useGetRoomInfo.ts b/frontend/src/pages/ReadyPage/useGetRoomInfo.ts index f3b118bd..d931dd61 100644 --- a/frontend/src/pages/ReadyPage/useGetRoomInfo.ts +++ b/frontend/src/pages/ReadyPage/useGetRoomInfo.ts @@ -21,5 +21,5 @@ export const useGetRoomInfo = () => { } }, [data?.isGameStart, roomId, navigate]); - return { data, isLoading, isError }; + return { members: data?.members, isLoading, isError }; }; From 1a828fb5d6fbdf8a8193901ede65c98ef02815fa Mon Sep 17 00:00:00 2001 From: novice0840 Date: Wed, 7 Aug 2024 15:00:15 +0900 Subject: [PATCH 0605/1013] =?UTF-8?q?refactor:=20suffix=EB=A5=BC=20mutatio?= =?UTF-8?q?n=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20#146?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/ReadyPage/useGameStart.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/pages/ReadyPage/useGameStart.ts b/frontend/src/pages/ReadyPage/useGameStart.ts index 6944a696..d65ca120 100644 --- a/frontend/src/pages/ReadyPage/useGameStart.ts +++ b/frontend/src/pages/ReadyPage/useGameStart.ts @@ -9,13 +9,13 @@ export const useGameStart = () => { const memberInfo = useRecoilValue(memberInfoState); const { roomId } = useParams(); - const startGameMutate = useMutation({ + const startGameMutation = useMutation({ mutationFn: () => startGame(Number(roomId)), }); const handleGameStart = () => { if (memberInfo.isMaster) { - startGameMutate.mutate(); + startGameMutation.mutate(); } }; From a2e42ca841a707b9c5f3c1f8aa2d21d94fd4cdd7 Mon Sep 17 00:00:00 2001 From: novice0840 Date: Wed, 7 Aug 2024 15:00:51 +0900 Subject: [PATCH 0606/1013] =?UTF-8?q?refactor:=20API=20=ED=95=A8=EC=88=98?= =?UTF-8?q?=20await=20=EC=B6=94=EA=B0=80=20#146?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/room.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/apis/room.ts b/frontend/src/apis/room.ts index 540ec1a1..ff9e377a 100644 --- a/frontend/src/apis/room.ts +++ b/frontend/src/apis/room.ts @@ -50,7 +50,7 @@ export const getRoomInfo = async (roomId: number): Promise => { // 게임 시작 export const startGame = async (roomId: number): Promise => { - fetcher.patch({ + await fetcher.patch({ url: API_URL.startGame(roomId), }); }; From b53abb2f50ad0c9ed705bb9136df88dd485862fd Mon Sep 17 00:00:00 2001 From: novice0840 Date: Wed, 7 Aug 2024 15:23:46 +0900 Subject: [PATCH 0607/1013] =?UTF-8?q?refactor:=20button=20disabled=20?= =?UTF-8?q?=EB=B0=B0=EA=B2=BD=EC=83=89=20=EB=B3=80=EA=B2=BD=20#146?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/common/Button/Button.styled.ts | 6 +----- frontend/src/components/common/Button/Button.tsx | 1 - frontend/src/pages/ReadyPage/ReadyPage.tsx | 7 ++++++- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/common/Button/Button.styled.ts b/frontend/src/components/common/Button/Button.styled.ts index 3aa4f39a..eb755b4a 100644 --- a/frontend/src/components/common/Button/Button.styled.ts +++ b/frontend/src/components/common/Button/Button.styled.ts @@ -28,16 +28,12 @@ export const buttonLayout = ({ border: none; border-radius: ${getBorderRadius(radius)}; - background-color: ${disabled ? Theme.color.peanut300 : Theme.color.peanut400}; + background-color: ${disabled ? Theme.color.gray300 : Theme.color.peanut400}; font-weight: bold; font-size: ${getFontSize(fontSize)}; cursor: ${disabled ? 'not-allowed' : 'pointer'}; - &:disabled { - background-color: ${Theme.color.peanut300}; - } - ${bottom && css` position: fixed; diff --git a/frontend/src/components/common/Button/Button.tsx b/frontend/src/components/common/Button/Button.tsx index a8309f6b..93b80e1f 100644 --- a/frontend/src/components/common/Button/Button.tsx +++ b/frontend/src/components/common/Button/Button.tsx @@ -26,7 +26,6 @@ const Button: React.FC = ({ return (
    ); }; From cf240d232724f43cebf4365d4572bde23aabb902 Mon Sep 17 00:00:00 2001 From: jhon3242 Date: Wed, 7 Aug 2024 16:17:14 +0900 Subject: [PATCH 0608/1013] =?UTF-8?q?fix:=20cors=20allowedOrigin=20?= =?UTF-8?q?=EA=B0=92=20=EC=83=9D=EC=84=B1=EC=9E=90=20=EC=A3=BC=EC=9E=85=20?= =?UTF-8?q?#145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/main/java/ddangkong/config/CorsConfig.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/ddangkong/config/CorsConfig.java b/backend/src/main/java/ddangkong/config/CorsConfig.java index 0cec8bc5..2cbba1fa 100644 --- a/backend/src/main/java/ddangkong/config/CorsConfig.java +++ b/backend/src/main/java/ddangkong/config/CorsConfig.java @@ -1,5 +1,6 @@ package ddangkong.config; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.web.servlet.config.annotation.CorsRegistry; @@ -8,7 +9,11 @@ @Configuration public class CorsConfig implements WebMvcConfigurer { - private final String corsOrigin = "*"; + private final String corsOrigin; + + public CorsConfig(@Value("${cors.origin}") String corsOrigin) { + this.corsOrigin = corsOrigin; + } @Override public void addCorsMappings(CorsRegistry registry) { From 69fe4565304457218c8c32c048df32b57bbda79e Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Wed, 7 Aug 2024 16:35:47 +0900 Subject: [PATCH 0609/1013] =?UTF-8?q?chore:=20application-dev.yml=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=20=EB=A1=9C=EC=A7=81=20=EC=A0=9C=EA=B1=B0=20?= =?UTF-8?q?#145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 7e3feda3..efb0b375 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -67,10 +67,6 @@ jobs: CONTAINER_NAME: ddangkong-api-dev steps: - - name: Setting application-dev.yml - run: | - echo "${{ secrets.APPLICATION_DEV_YML }}" > ~/application-dev.yml - - name: Log in to Docker Hub uses: docker/login-action@v3 with: From ad3de4dcea8baaaa5a70da8cf7a96cdde3c33cd6 Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 16:35:47 +0900 Subject: [PATCH 0610/1013] =?UTF-8?q?refactor:=20mock=20api=20=EC=A3=BC?= =?UTF-8?q?=EC=86=8C=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/constants/url.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/constants/url.ts b/frontend/src/constants/url.ts index bbc3e6d7..e3647522 100644 --- a/frontend/src/constants/url.ts +++ b/frontend/src/constants/url.ts @@ -21,7 +21,7 @@ export const MOCK_API_URL = { balanceContent: `${BASE_URL}/api/balances/rooms/:roomId/content`, vote: `${BASE_URL}/api/balances/rooms/:roomId/contents/:contentId/votes`, roundVoteResult: `${BASE_URL}/api/balances/rooms/:roomId/contents/:contentId/vote-result`, - myGameStatus: `${BASE_URL}/api/balances/rooms/:roomId?myRound=:myRound`, + myGameStatus: `${BASE_URL}/api/balances/rooms/:roomId?round=:round`, moveNextRound: `${BASE_URL}/api/balances/rooms/:roomId/next-round`, finalResult: `${BASE_URL}/api/balances/rooms/:roomId/final`, room: `${BASE_URL}/api/balances/rooms`, From 817f86c7e789ca5bb6e241da8c22e16877f6d8ab Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 7 Aug 2024 16:37:07 +0900 Subject: [PATCH 0611/1013] =?UTF-8?q?test:=20=EB=B0=A9=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EC=97=90=EC=84=9C=20Req?= =?UTF-8?q?uestBody=EB=A5=BC=20=EA=B0=9D=EC=B2=B4=EB=A5=BC=20=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD=20#14?= =?UTF-8?q?2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/balance/room/RoomControllerTest.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java index c23ed369..a033f767 100644 --- a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java @@ -5,6 +5,7 @@ import ddangkong.controller.BaseControllerTest; import ddangkong.controller.balance.room.dto.RoomInfoResponse; +import ddangkong.controller.balance.room.dto.RoomJoinRequest; import ddangkong.controller.balance.room.dto.RoomJoinResponse; import ddangkong.controller.balance.room.dto.RoomSettingRequest; import ddangkong.domain.balance.content.BalanceContent; @@ -31,9 +32,7 @@ class 방_생성 { @Test void 방을_생성할_수_있다() { // given - String nickname = "방장"; - Map body = new HashMap<>(); - body.put("nickname", nickname); + RoomJoinRequest body = new RoomJoinRequest("방장"); // when & then RestAssured.given().log().all() @@ -48,9 +47,7 @@ class 방_생성 { @Test void 방을_생성한_사용자는_방장이다() { // given - String nickname = "방장"; - Map body = new HashMap<>(); - body.put("nickname", nickname); + RoomJoinRequest body = new RoomJoinRequest("방장"); // when & then RoomJoinResponse actual = RestAssured.given().log().all() From 65c84061d8e7201bc8bc36d5e0a64fe0a8601437 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Wed, 7 Aug 2024 16:37:40 +0900 Subject: [PATCH 0612/1013] =?UTF-8?q?chore:=20=EB=8F=84=EC=BB=A4=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=82=AD=EC=A0=9C=20=ED=9B=84=20?= =?UTF-8?q?=EB=AC=B8=EA=B5=AC=20=EC=B6=9C=EB=A0=A5=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index efb0b375..9b3e4129 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -77,19 +77,20 @@ jobs: run: | CONTAINER_ID=$(sudo docker ps -aqf name=$CONTAINER_NAME) if [ -n "${CONTAINER_ID}" ]; then - sudo docker rm -f ${CONTAINER_ID} - echo "Container ${CONTAINER_ID} is stopped and removed." + sudo docker rm -f ${CONTAINER_ID} + echo "Container ${CONTAINER_ID} is stopped and removed." else - echo "No previous container found with name. Skipping removal." + echo "No previous container found with name. Skipping removal." fi - name: Remove previous Docker image run: | IMAGE_ID=$(sudo docker images --filter=reference=ddangkong/ddangkong-api-dev --format "{{.ID}}") if [ -n "${IMAGE_ID}" ]; then - sudo docker rmi ${IMAGE_ID} + sudo docker rmi ${IMAGE_ID} + echo "Image ${IMAGE_ID} is removed." else - echo "No previous image found with repository name. Skipping removal." + echo "No previous image found with repository name. Skipping removal." fi - name: Pull docker image From 7e6d5909198ebe6a8adcf096eca8a05a29c46cb9 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 7 Aug 2024 16:37:56 +0900 Subject: [PATCH 0613/1013] =?UTF-8?q?test:=20ControllerTest=EC=97=90?= =?UTF-8?q?=EC=84=9C=20path=20parameter=EB=A5=BC=20=EB=94=B0=EB=A1=9C=20?= =?UTF-8?q?=EB=B0=9B=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD=20#142?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/balance/room/RoomControllerTest.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java index a033f767..b5c7ea47 100644 --- a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java @@ -69,7 +69,8 @@ class 밸런스_게임_방_정보_조회 { void 게임_방_정보_조회() { //when RoomInfoResponse actual = RestAssured.given() - .when().get("/api/balances/rooms/1") + .pathParam("roomId", 1L) + .when().get("/api/balances/rooms/{roomId}") .then().contentType(ContentType.JSON).log().all() .statusCode(200) .extract().as(RoomInfoResponse.class); @@ -119,8 +120,9 @@ class 방_참가 { // when & then RestAssured.given().log().all() .contentType(ContentType.JSON) + .pathParam("roomId", 1L) .body(body) - .when().post("/api/balances/rooms/1/members") + .when().post("/api/balances/rooms/{roomId}/members") .then().log().all() .statusCode(201) .extract().as(RoomJoinResponse.class); @@ -135,8 +137,9 @@ class 방_참가 { // when & then RoomJoinResponse actual = RestAssured.given().log().all() .contentType(ContentType.JSON) + .pathParam("roomId", 1L) .body(body) - .when().post("/api/balances/rooms/1/members") + .when().post("/api/balances/rooms/{roomId}/members") .then().log().all() .statusCode(201) .extract().as(RoomJoinResponse.class); From d11ea220f515eea130719912d58c43e6660795a3 Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 16:45:50 +0900 Subject: [PATCH 0614/1013] =?UTF-8?q?refactor:=20=ED=88=AC=ED=91=9C=20?= =?UTF-8?q?=ED=98=84=ED=99=A9=20=ED=8E=98=EC=9D=B4=EC=A7=80=20route=20path?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/TabContentContainer/TabContentContainer.tsx | 3 ++- frontend/src/constants/routes.ts | 1 + frontend/src/router/index.tsx | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/TabContentContainer/TabContentContainer.tsx b/frontend/src/components/TabContentContainer/TabContentContainer.tsx index 5b58b51c..6908494f 100644 --- a/frontend/src/components/TabContentContainer/TabContentContainer.tsx +++ b/frontend/src/components/TabContentContainer/TabContentContainer.tsx @@ -14,6 +14,7 @@ import { } from './TabContentContainer.styled'; import useTotalCountAnimation from '../RoundVoteContainer/RoundVoteContainer.hook'; +import { ROUTES } from '@/constants/routes'; import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; import useRoundVoteResultQuery from '@/hooks/useRoundVoteResultQuery'; import { Group, Total } from '@/types/roundVoteResult'; @@ -47,7 +48,7 @@ const TabContentContainer = ({ isGroupTabActive }: TabContentContainerProps) => const isBigFirstOption = roundResult && roundResult.firstOption.percent >= 50; const goToVoteStatus = () => { - navigate('/round/result/status'); + navigate(ROUTES.roundResultStatus(Number(roomId))); }; if (!roundResult) return
    데이터가 없습니다
    ; diff --git a/frontend/src/constants/routes.ts b/frontend/src/constants/routes.ts index 4d42e57c..b3ac59ea 100644 --- a/frontend/src/constants/routes.ts +++ b/frontend/src/constants/routes.ts @@ -6,4 +6,5 @@ export const ROUTES = { roundResult: (roomId: number) => `/${roomId}/round/result`, roundResultVote: '/round/result/vote', gameResult: '/game/result', + roundResultStatus: (roomId: number) => `/${roomId}/round/result/status`, } as const; diff --git a/frontend/src/router/index.tsx b/frontend/src/router/index.tsx index c3ab9d1b..9376bf99 100644 --- a/frontend/src/router/index.tsx +++ b/frontend/src/router/index.tsx @@ -16,7 +16,7 @@ export const router = createBrowserRouter([ element: , }, { - path: 'round/result/status', + path: ':roomId/round/result/status', element: , }, { From bf5b3f524b88d8abd3e1e8cb05a93b24246d853a Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 16:48:46 +0900 Subject: [PATCH 0615/1013] =?UTF-8?q?test:=20=EB=9D=BC=EC=9A=B4=EB=93=9C?= =?UTF-8?q?=20=EB=98=90=EB=8A=94=20=EA=B2=8C=EC=9E=84=EC=9D=B4=20=EB=81=9D?= =?UTF-8?q?=EB=82=AC=EB=8A=94=EC=A7=80=20=EC=97=AC=EB=B6=80=20=ED=8F=B4?= =?UTF-8?q?=EB=A7=81=20msw=20=EC=97=B0=EA=B2=B0=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/mocks/handlers/balanceContentHandler.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frontend/src/mocks/handlers/balanceContentHandler.ts b/frontend/src/mocks/handlers/balanceContentHandler.ts index 347ea961..98949347 100644 --- a/frontend/src/mocks/handlers/balanceContentHandler.ts +++ b/frontend/src/mocks/handlers/balanceContentHandler.ts @@ -1,6 +1,7 @@ import { http, HttpResponse } from 'msw'; import BALANCE_CONTENT from '../data/balanceContent.json'; +import MY_GAME_STATUS from '../data/myGameStatus.json'; import ROUND_VOTE_IS_FINISHED from '../data/roundVoteIsFinished.json'; import { MOCK_API_URL } from '@/constants/url'; @@ -18,7 +19,12 @@ const fetchIsFinishedHandler = () => { return HttpResponse.json(ROUND_VOTE_IS_FINISHED); }; +const getMyGameStatus = () => { + return HttpResponse.json(MY_GAME_STATUS); +}; + export const contentHandler = [ http.get(MOCK_API_URL.balanceContent, fetchBalanceContentHandler), http.get(MOCK_API_URL.roundVoteIsFinished, fetchIsFinishedHandler), + http.get(MOCK_API_URL.myGameStatus, getMyGameStatus), ]; From cc423b2de3032d3804b23feeb58e575a088527bc Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Wed, 7 Aug 2024 16:51:36 +0900 Subject: [PATCH 0616/1013] =?UTF-8?q?refactor:=20=EB=B3=80=EC=88=98?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD,=20null=20=EB=A6=AC=ED=84=B4=20#?= =?UTF-8?q?144?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: leegwichan --- .../ddangkong/aop/logging/RequestLoggingAspect.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/backend/src/main/java/ddangkong/aop/logging/RequestLoggingAspect.java b/backend/src/main/java/ddangkong/aop/logging/RequestLoggingAspect.java index 9a185529..8b5d0704 100644 --- a/backend/src/main/java/ddangkong/aop/logging/RequestLoggingAspect.java +++ b/backend/src/main/java/ddangkong/aop/logging/RequestLoggingAspect.java @@ -37,10 +37,10 @@ public void logController(JoinPoint joinPoint) { HttpServletRequest request = getHttpServletRequest(); String uri = request.getRequestURI(); String httpMethod = request.getMethod(); - String parameters = getParameters(request); + String queryParameters = getQueryParameters(request); String body = getBody(joinPoint); - log.info("Request Logging : {} {} body: {} parameters : {}", httpMethod, uri, body, parameters); + log.info("Request Logging: {} {} body - {} parameters - {}", httpMethod, uri, body, queryParameters); } private HttpServletRequest getHttpServletRequest() { @@ -48,12 +48,17 @@ private HttpServletRequest getHttpServletRequest() { return requestAttributes.getRequest(); } - private String getParameters(HttpServletRequest request) { - return request.getParameterMap() + private String getQueryParameters(HttpServletRequest request) { + String queryParameters = request.getParameterMap() .entrySet() .stream() .map(entry -> "%s = %s".formatted(entry.getKey(), entry.getValue()[0])) .collect(joining(", ")); + + if (queryParameters.isEmpty()) { + return null; + } + return queryParameters; } private String getBody(JoinPoint joinPoint) { From 31933751440ad7e0fa7c3450fc1d7deee429806b Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 16:55:32 +0900 Subject: [PATCH 0617/1013] =?UTF-8?q?refactor:=20api=20=ED=98=B8=EC=B6=9C?= =?UTF-8?q?=20=ED=95=A8=EC=88=98=EB=AA=85=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F?= =?UTF-8?q?=20=EB=B0=A9=EC=9E=A5=20=EC=97=AC=EB=B6=80=EC=97=90=20=EB=94=B0?= =?UTF-8?q?=EB=A5=B8=20=EB=B2=84=ED=8A=BC=20=EC=8A=A4=ED=83=80=EC=9D=BC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NextRoundButton/NextRoundButton.tsx | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx index 9817d8fb..5c81f082 100644 --- a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx +++ b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx @@ -5,9 +5,10 @@ import useMoveNextRoundMutation from './NextRoundButton.hook'; import Button from '../Button/Button'; import { bottomButtonLayout } from '../Button/Button.styled'; -import { ROUTES } from '@/constants/routes'; import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; +import useMyGameStatusQuery from '@/hooks/useMyGameStatusQuery'; import { memberInfoState } from '@/recoil/atom'; +import { Theme } from '@/styles/Theme'; const NextRoundButton = () => { const { roomId } = useParams(); @@ -15,26 +16,33 @@ const NextRoundButton = () => { const { balanceContent } = useBalanceContentQuery(); const { mutateAsync: moveNextRound } = useMoveNextRoundMutation(Number(roomId)); const memberInfo = useRecoilValue(memberInfoState); - const isLastRound = balanceContent?.currentRound === balanceContent?.totalRound; - const goToGameResult = () => { - navigate(ROUTES.gameResult, { replace: true }); + const fetchGameResult = () => { + // TODO: 게임 결과 API 추후 연결 }; - const goToNextRound = async () => { + const fetchNextRound = async () => { await moveNextRound(); - navigate(ROUTES.game(Number(roomId)), { replace: true }); }; return (
    -
    ); }; From 37b768a258d7db6689eecb35ce5b99db3744ba8b Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 17:14:07 +0900 Subject: [PATCH 0618/1013] =?UTF-8?q?refactor:=20=EA=B2=8C=EC=9E=84=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B4=EB=93=9C=EC=99=80=20=EA=B2=B0=EA=B3=BC=20?= =?UTF-8?q?=EC=97=AC=EB=B6=80=EC=97=90=20=EB=94=B0=EB=9D=BC=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EB=A5=BC=20=EC=9D=B4=EB=8F=99=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EC=BB=A4=EC=8A=A4=ED=85=80=20=ED=9B=85=20=EB=B6=88?= =?UTF-8?q?=ED=95=84=EC=9A=94=ED=95=9C=20=EB=A1=9C=EC=A7=81=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OptionParticipantsContainer.tsx | 11 +++++++- .../RoundVoteContainer/RoundVoteContainer.tsx | 3 --- .../TabContentContainer.tsx | 3 +++ frontend/src/hooks/useMyGameStatus.ts | 27 +++++++------------ 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx index 48447899..11d4f65b 100644 --- a/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx +++ b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx @@ -7,10 +7,19 @@ import { import OptionParticipants from '../OptionParticipants/OptionParticipants'; import TopicContainer from '../TopicContainer/TopicContainer'; +import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; import useMyGameStatus from '@/hooks/useMyGameStatus'; +import useRoundVoteResultQuery from '@/hooks/useRoundVoteResultQuery'; const OptionParticipantsContainer = () => { - const { groupRoundResult } = useMyGameStatus(); + const { roomId } = useParams(); + const { balanceContent } = useBalanceContentQuery(); + const { groupRoundResult } = useRoundVoteResultQuery({ + roomId: Number(roomId), + contentId: balanceContent?.contentId, + }); + + useMyGameStatus({ roomId: Number(roomId), balanceContent }); if (!groupRoundResult) { return null; diff --git a/frontend/src/components/RoundVoteContainer/RoundVoteContainer.tsx b/frontend/src/components/RoundVoteContainer/RoundVoteContainer.tsx index 148ec630..e5cd97a3 100644 --- a/frontend/src/components/RoundVoteContainer/RoundVoteContainer.tsx +++ b/frontend/src/components/RoundVoteContainer/RoundVoteContainer.tsx @@ -4,12 +4,9 @@ import { tabLayout, tabWrapper } from './RoundVoteContainer.styled'; import RoundResultTab from '../RoundResultTab/RoundResultTab'; import TabContentContainer from '../TabContentContainer/TabContentContainer'; -import useMyGameStatus from '@/hooks/useMyGameStatus'; - const RoundVoteContainer = () => { const [activeTab, setActiveTab] = useState<'group' | 'total'>('group'); const isGroupTabActive = activeTab === 'group'; - useMyGameStatus(); const handleClickTab = (clickedTab: 'group' | 'total') => { setActiveTab(clickedTab); diff --git a/frontend/src/components/TabContentContainer/TabContentContainer.tsx b/frontend/src/components/TabContentContainer/TabContentContainer.tsx index 6908494f..d685ed3b 100644 --- a/frontend/src/components/TabContentContainer/TabContentContainer.tsx +++ b/frontend/src/components/TabContentContainer/TabContentContainer.tsx @@ -16,6 +16,7 @@ import useTotalCountAnimation from '../RoundVoteContainer/RoundVoteContainer.hoo import { ROUTES } from '@/constants/routes'; import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; +import useMyGameStatus from '@/hooks/useMyGameStatus'; import useRoundVoteResultQuery from '@/hooks/useRoundVoteResultQuery'; import { Group, Total } from '@/types/roundVoteResult'; @@ -37,6 +38,8 @@ const TabContentContainer = ({ isGroupTabActive }: TabContentContainerProps) => contentId: balanceContent?.contentId, }); + useMyGameStatus({ roomId: Number(roomId), balanceContent }); + const { animatedFirstPercent, animatedSecondPercent, diff --git a/frontend/src/hooks/useMyGameStatus.ts b/frontend/src/hooks/useMyGameStatus.ts index 1ab13eb3..85610653 100644 --- a/frontend/src/hooks/useMyGameStatus.ts +++ b/frontend/src/hooks/useMyGameStatus.ts @@ -1,25 +1,21 @@ import { useEffect } from 'react'; -import { useNavigate, useParams } from 'react-router-dom'; +import { useNavigate } from 'react-router-dom'; -import useBalanceContentQuery from './useBalanceContentQuery'; import useMyGameStatusQuery from './useMyGameStatusQuery'; -import useRoundVoteResultQuery from './useRoundVoteResultQuery'; import { ROUTES } from '@/constants/routes'; +import { BalanceContent } from '@/types/balanceContent'; -const useMyGameStatus = () => { - const { roomId } = useParams(); - const navigate = useNavigate(); - - const { balanceContent } = useBalanceContentQuery(); +interface UseMyGameStatusProps { + roomId: number; + balanceContent: BalanceContent | undefined; +} - const { groupRoundResult, totalResult } = useRoundVoteResultQuery({ - roomId: Number(roomId), - contentId: balanceContent?.contentId, - }); +const useMyGameStatus = ({ roomId, balanceContent }: UseMyGameStatusProps) => { + const navigate = useNavigate(); const { isRoundFinished, isGameFinished } = useMyGameStatusQuery({ - roomId: Number(roomId), + roomId, balanceContent, }); @@ -39,11 +35,6 @@ const useMyGameStatus = () => { goToNextRound(); } }, [isRoundFinished, isGameFinished]); - - return { - groupRoundResult, - totalResult, - }; }; export default useMyGameStatus; From 0f0ad98dc76dce65d668ec22a407952cf4d4b72e Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 17:19:54 +0900 Subject: [PATCH 0619/1013] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20async=20=EC=82=AD=EC=A0=9C=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useMyGameStatus.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/hooks/useMyGameStatus.ts b/frontend/src/hooks/useMyGameStatus.ts index 85610653..cc841d73 100644 --- a/frontend/src/hooks/useMyGameStatus.ts +++ b/frontend/src/hooks/useMyGameStatus.ts @@ -23,7 +23,7 @@ const useMyGameStatus = ({ roomId, balanceContent }: UseMyGameStatusProps) => { navigate(ROUTES.gameResult); }; - const goToNextRound = async () => { + const goToNextRound = () => { navigate(ROUTES.game(Number(roomId))); }; From 34cc0930d953e3405c9eca865c1e68697b2413f4 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Wed, 7 Aug 2024 17:20:28 +0900 Subject: [PATCH 0620/1013] =?UTF-8?q?chore:=20sentry=EC=97=90=20source=20m?= =?UTF-8?q?ap=20=EC=97=85=EB=A1=9C=EB=93=9C=20=ED=9B=84=20=EB=B9=8C?= =?UTF-8?q?=EB=93=9C=20=EA=B2=B0=EA=B3=BC=EB=AC=BC=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0=20#137?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.gitignore | 4 +- frontend/package-lock.json | 423 ++++++++++++++++++++++++++++++++ frontend/package.json | 1 + frontend/webpack.config.prod.js | 12 + 4 files changed, 439 insertions(+), 1 deletion(-) diff --git a/frontend/.gitignore b/frontend/.gitignore index f4ea8483..e1d05f0e 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -28,4 +28,6 @@ dist-ssr .env.production *storybook.log -storybook-static \ No newline at end of file +storybook-static +# Sentry Config File +.env.sentry-build-plugin diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 8de20d10..dd643e53 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -26,6 +26,7 @@ "@emotion/babel-plugin": "^11.12.0", "@emotion/babel-preset-css-prop": "^11.11.0", "@sentry/react": "^8.23.0", + "@sentry/webpack-plugin": "^2.22.0", "@storybook/addon-essentials": "^8.2.2", "@storybook/addon-interactions": "^8.2.2", "@storybook/addon-links": "^8.2.2", @@ -4025,6 +4026,15 @@ "node": ">=14.18" } }, + "node_modules/@sentry/babel-plugin-component-annotate": { + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-2.22.0.tgz", + "integrity": "sha512-UzH+NNhgnOo6UFku3C4TEz+pO/yDcIA5FKTJvLbJ7lQwAjsqLs3DZWm4cCA08skICb8mULArF6S/dn5/butVCA==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, "node_modules/@sentry/browser": { "version": "8.23.0", "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.23.0.tgz", @@ -4043,6 +4053,314 @@ "node": ">=14.18" } }, + "node_modules/@sentry/bundler-plugin-core": { + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-2.22.0.tgz", + "integrity": "sha512-/xXN8o7565WMsewBnQFfjm0E5wqhYsegg++HJ5RjrY/cTM4qcd/ven44GEMxqGFJitZizvkk3NHszaHylzcRUw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.18.5", + "@sentry/babel-plugin-component-annotate": "2.22.0", + "@sentry/cli": "^2.33.1", + "dotenv": "^16.3.1", + "find-up": "^5.0.0", + "glob": "^9.3.2", + "magic-string": "0.30.8", + "unplugin": "1.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@sentry/bundler-plugin-core/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sentry/bundler-plugin-core/node_modules/glob": { + "version": "9.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@sentry/bundler-plugin-core/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sentry/bundler-plugin-core/node_modules/magic-string": { + "version": "0.30.8", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", + "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@sentry/bundler-plugin-core/node_modules/minimatch": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", + "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@sentry/bundler-plugin-core/node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry/bundler-plugin-core/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sentry/bundler-plugin-core/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sentry/bundler-plugin-core/node_modules/unplugin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.0.1.tgz", + "integrity": "sha512-aqrHaVBWW1JVKBHmGo33T5TxeL0qWzfvjWokObHA9bYmN7eNDkwOxmLjhioHl9878qDFMAaT51XNroRyuz7WxA==", + "dev": true, + "dependencies": { + "acorn": "^8.8.1", + "chokidar": "^3.5.3", + "webpack-sources": "^3.2.3", + "webpack-virtual-modules": "^0.5.0" + } + }, + "node_modules/@sentry/bundler-plugin-core/node_modules/webpack-virtual-modules": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.5.0.tgz", + "integrity": "sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==", + "dev": true + }, + "node_modules/@sentry/bundler-plugin-core/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sentry/cli": { + "version": "2.33.1", + "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.33.1.tgz", + "integrity": "sha512-dUlZ4EFh98VFRPJ+f6OW3JEYQ7VvqGNMa0AMcmvk07ePNeK/GicAWmSQE4ZfJTTl80ul6HZw1kY01fGQOQlVRA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.7", + "progress": "^2.0.3", + "proxy-from-env": "^1.1.0", + "which": "^2.0.2" + }, + "bin": { + "sentry-cli": "bin/sentry-cli" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@sentry/cli-darwin": "2.33.1", + "@sentry/cli-linux-arm": "2.33.1", + "@sentry/cli-linux-arm64": "2.33.1", + "@sentry/cli-linux-i686": "2.33.1", + "@sentry/cli-linux-x64": "2.33.1", + "@sentry/cli-win32-i686": "2.33.1", + "@sentry/cli-win32-x64": "2.33.1" + } + }, + "node_modules/@sentry/cli-darwin": { + "version": "2.33.1", + "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.33.1.tgz", + "integrity": "sha512-+4/VIx/E1L2hChj5nGf5MHyEPHUNHJ/HoG5RY+B+vyEutGily1c1+DM2bum7RbD0xs6wKLIyup5F02guzSzG8A==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-linux-arm": { + "version": "2.33.1", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.33.1.tgz", + "integrity": "sha512-zbxEvQju+tgNvzTOt635le4kS/Fbm2XC2RtYbCTs034Vb8xjrAxLnK0z1bQnStUV8BkeBHtsNVrG+NSQDym2wg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux", + "freebsd" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-linux-arm64": { + "version": "2.33.1", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.33.1.tgz", + "integrity": "sha512-DbGV56PRKOLsAZJX27Jt2uZ11QfQEMmWB4cIvxkKcFVE+LJP4MVA+MGGRUL6p+Bs1R9ZUuGbpKGtj0JiG6CoXw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux", + "freebsd" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-linux-i686": { + "version": "2.33.1", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.33.1.tgz", + "integrity": "sha512-g2LS4oPXkPWOfKWukKzYp4FnXVRRSwBxhuQ9eSw2peeb58ZIObr4YKGOA/8HJRGkooBJIKGaAR2mH2Pk1TKaiA==", + "cpu": [ + "x86", + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux", + "freebsd" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-linux-x64": { + "version": "2.33.1", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.33.1.tgz", + "integrity": "sha512-IV3dcYV/ZcvO+VGu9U6kuxSdbsV2kzxaBwWUQxtzxJ+cOa7J8Hn1t0koKGtU53JVZNBa06qJWIcqgl4/pCuKIg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux", + "freebsd" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-win32-i686": { + "version": "2.33.1", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.33.1.tgz", + "integrity": "sha512-F7cJySvkpzIu7fnLKNHYwBzZYYwlhoDbAUnaFX0UZCN+5DNp/5LwTp37a5TWOsmCaHMZT4i9IO4SIsnNw16/zQ==", + "cpu": [ + "x86", + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-win32-x64": { + "version": "2.33.1", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.33.1.tgz", + "integrity": "sha512-8VyRoJqtb2uQ8/bFRKNuACYZt7r+Xx0k2wXRGTyH05lCjAiVIXn7DiS2BxHFty7M1QEWUCMNsb/UC/x/Cu2wuA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, "node_modules/@sentry/core": { "version": "8.23.0", "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.23.0.tgz", @@ -4096,6 +4414,54 @@ "node": ">=14.18" } }, + "node_modules/@sentry/webpack-plugin": { + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/@sentry/webpack-plugin/-/webpack-plugin-2.22.0.tgz", + "integrity": "sha512-u2brctki0AMCoZksdAConQSYE6PokRVeZ4YYsbnJYkAi0KuaQnczsRwS9e2L0bK2CmZ7QdyYcrjaXHNlXaFDbQ==", + "dev": true, + "dependencies": { + "@sentry/bundler-plugin-core": "2.22.0", + "unplugin": "1.0.1", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "webpack": ">=4.40.0" + } + }, + "node_modules/@sentry/webpack-plugin/node_modules/unplugin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.0.1.tgz", + "integrity": "sha512-aqrHaVBWW1JVKBHmGo33T5TxeL0qWzfvjWokObHA9bYmN7eNDkwOxmLjhioHl9878qDFMAaT51XNroRyuz7WxA==", + "dev": true, + "dependencies": { + "acorn": "^8.8.1", + "chokidar": "^3.5.3", + "webpack-sources": "^3.2.3", + "webpack-virtual-modules": "^0.5.0" + } + }, + "node_modules/@sentry/webpack-plugin/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@sentry/webpack-plugin/node_modules/webpack-virtual-modules": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.5.0.tgz", + "integrity": "sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==", + "dev": true + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "dev": true, @@ -15589,11 +15955,53 @@ "node": "*" } }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/node-fetch-native": { "version": "1.6.4", "dev": true, "license": "MIT" }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/node-forge": { "version": "1.3.1", "dev": true, @@ -16620,6 +17028,15 @@ "dev": true, "license": "MIT" }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/prompts": { "version": "2.4.2", "dev": true, @@ -16662,6 +17079,12 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, "node_modules/psl": { "version": "1.9.0", "dev": true, diff --git a/frontend/package.json b/frontend/package.json index afd5cfab..3dd81aec 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -36,6 +36,7 @@ "@emotion/babel-plugin": "^11.12.0", "@emotion/babel-preset-css-prop": "^11.11.0", "@sentry/react": "^8.23.0", + "@sentry/webpack-plugin": "^2.22.0", "@storybook/addon-essentials": "^8.2.2", "@storybook/addon-interactions": "^8.2.2", "@storybook/addon-links": "^8.2.2", diff --git a/frontend/webpack.config.prod.js b/frontend/webpack.config.prod.js index b16b8185..2fca7f2b 100644 --- a/frontend/webpack.config.prod.js +++ b/frontend/webpack.config.prod.js @@ -1,5 +1,6 @@ const { merge } = require('webpack-merge'); const common = require('./webpack.config.common.js'); +const { sentryWebpackPlugin } = require('@sentry/webpack-plugin'); module.exports = merge(common, { mode: 'production', @@ -7,6 +8,17 @@ module.exports = merge(common, { port: 3000, historyApiFallback: true, }, + devtool: 'hidden-source-map', + plugins: [ + sentryWebpackPlugin({ + authToken: process.env.SENTRY_AUTH_TOKEN, + org: 'ddangkong', + project: 'ddangkong-front', + sourcemaps: { + filesToDeleteAfterUpload: '**/*.js.map', + }, + }), + ], module: { rules: [ { From 8c1f4d546409210e60db85ef97c45e72217e74f7 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Wed, 7 Aug 2024 17:21:38 +0900 Subject: [PATCH 0621/1013] =?UTF-8?q?feat:=20API=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=8B=9C=20sentry=20=EB=A1=9C=20=EC=B6=94=EC=A0=81=20#137?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/fetcher.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/src/apis/fetcher.ts b/frontend/src/apis/fetcher.ts index 66bff23a..a2ba3816 100644 --- a/frontend/src/apis/fetcher.ts +++ b/frontend/src/apis/fetcher.ts @@ -1,3 +1,5 @@ +import { captureException } from '@sentry/react'; + interface RequestProps { url: string; method: 'GET' | 'POST' | 'DELETE' | 'PATCH' | 'PUT'; @@ -16,6 +18,7 @@ const fetcher = { }); if (!response.ok) { + captureException('fetch API ERROR'); throw new Error('fetch fail error'); } From 87283fb88bb75465fe353d4ae4d02fd7a419fa02 Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 17:30:31 +0900 Subject: [PATCH 0622/1013] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EB=A1=9C=EC=A7=81=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/common/NextRoundButton/NextRoundButton.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx index 5c81f082..bd34e888 100644 --- a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx +++ b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx @@ -6,13 +6,11 @@ import Button from '../Button/Button'; import { bottomButtonLayout } from '../Button/Button.styled'; import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; -import useMyGameStatusQuery from '@/hooks/useMyGameStatusQuery'; import { memberInfoState } from '@/recoil/atom'; import { Theme } from '@/styles/Theme'; const NextRoundButton = () => { const { roomId } = useParams(); - const navigate = useNavigate(); const { balanceContent } = useBalanceContentQuery(); const { mutateAsync: moveNextRound } = useMoveNextRoundMutation(Number(roomId)); const memberInfo = useRecoilValue(memberInfoState); From 4ee82c9b19930d79af59df8501646f4e717244c8 Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 17:32:27 +0900 Subject: [PATCH 0623/1013] =?UTF-8?q?refactor:=20balanceContent=20?= =?UTF-8?q?=EC=A0=84=EC=B2=B4=EB=A5=BC=20=EB=B0=9B=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EA=B3=A0=20=ED=95=84=EC=9A=94=ED=95=9C=20currentRound=EB=A7=8C?= =?UTF-8?q?=20=EB=B0=9B=EB=8F=84=EB=A1=9D=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=ED=9B=85=20=EC=88=98=EC=A0=95=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OptionParticipantsContainer.tsx | 3 ++- .../TabContentContainer/TabContentContainer.tsx | 3 ++- frontend/src/hooks/useMyGameStatus.ts | 7 +++---- frontend/src/hooks/useMyGameStatusQuery.ts | 13 ++++++------- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx index 11d4f65b..14be9b19 100644 --- a/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx +++ b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx @@ -14,12 +14,13 @@ import useRoundVoteResultQuery from '@/hooks/useRoundVoteResultQuery'; const OptionParticipantsContainer = () => { const { roomId } = useParams(); const { balanceContent } = useBalanceContentQuery(); + const currentRound = balanceContent?.currentRound; const { groupRoundResult } = useRoundVoteResultQuery({ roomId: Number(roomId), contentId: balanceContent?.contentId, }); - useMyGameStatus({ roomId: Number(roomId), balanceContent }); + useMyGameStatus({ roomId: Number(roomId), currentRound }); if (!groupRoundResult) { return null; diff --git a/frontend/src/components/TabContentContainer/TabContentContainer.tsx b/frontend/src/components/TabContentContainer/TabContentContainer.tsx index d685ed3b..7d91ffa8 100644 --- a/frontend/src/components/TabContentContainer/TabContentContainer.tsx +++ b/frontend/src/components/TabContentContainer/TabContentContainer.tsx @@ -33,12 +33,13 @@ const TabContentContainer = ({ isGroupTabActive }: TabContentContainerProps) => const navigate = useNavigate(); const { balanceContent } = useBalanceContentQuery(); + const currentRound = balanceContent?.currentRound; const { groupRoundResult, totalResult } = useRoundVoteResultQuery({ roomId: Number(roomId), contentId: balanceContent?.contentId, }); - useMyGameStatus({ roomId: Number(roomId), balanceContent }); + useMyGameStatus({ roomId: Number(roomId), currentRound }); const { animatedFirstPercent, diff --git a/frontend/src/hooks/useMyGameStatus.ts b/frontend/src/hooks/useMyGameStatus.ts index cc841d73..f8f8d0d3 100644 --- a/frontend/src/hooks/useMyGameStatus.ts +++ b/frontend/src/hooks/useMyGameStatus.ts @@ -4,19 +4,18 @@ import { useNavigate } from 'react-router-dom'; import useMyGameStatusQuery from './useMyGameStatusQuery'; import { ROUTES } from '@/constants/routes'; -import { BalanceContent } from '@/types/balanceContent'; interface UseMyGameStatusProps { roomId: number; - balanceContent: BalanceContent | undefined; + currentRound: number | undefined; } -const useMyGameStatus = ({ roomId, balanceContent }: UseMyGameStatusProps) => { +const useMyGameStatus = ({ roomId, currentRound }: UseMyGameStatusProps) => { const navigate = useNavigate(); const { isRoundFinished, isGameFinished } = useMyGameStatusQuery({ roomId, - balanceContent, + currentRound, }); const goToGameResult = () => { diff --git a/frontend/src/hooks/useMyGameStatusQuery.ts b/frontend/src/hooks/useMyGameStatusQuery.ts index b4c16acc..43339981 100644 --- a/frontend/src/hooks/useMyGameStatusQuery.ts +++ b/frontend/src/hooks/useMyGameStatusQuery.ts @@ -2,26 +2,25 @@ import { useQuery } from '@tanstack/react-query'; import { checkMyGameStatus } from '@/apis/balanceContent'; import { QUERY_KEYS } from '@/constants/queryKeys'; -import { BalanceContent } from '@/types/balanceContent'; interface useMyGameStatusQueryProps { - balanceContent: BalanceContent | undefined; + currentRound: number | undefined; roomId: number; } -const useMyGameStatusQuery = ({ roomId, balanceContent }: useMyGameStatusQueryProps) => { +const useMyGameStatusQuery = ({ roomId, currentRound }: useMyGameStatusQueryProps) => { const myGameStatusQuery = useQuery({ - queryKey: [QUERY_KEYS.myGameStatus, balanceContent, roomId, balanceContent?.currentRound], + queryKey: [QUERY_KEYS.myGameStatus, roomId, currentRound], queryFn: () => { - if (!balanceContent) { + if (!currentRound) { throw new Error('balanceContent 가 존재하지 않습니다.'); } return checkMyGameStatus({ roomId: roomId, - currentRound: balanceContent.currentRound, + currentRound: currentRound, }); }, - enabled: !!balanceContent, + enabled: !!currentRound, staleTime: 0, refetchInterval: 1000, }); From 366a4ebbdb4e87ff0a3d635cfd022d774b0f982d Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 17:45:40 +0900 Subject: [PATCH 0624/1013] =?UTF-8?q?refactor:=20=EA=B2=8C=EC=9E=84=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=20=EA=B2=BD=EB=A1=9C=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EB=B0=8F=20=EC=A0=81=EC=9A=A9=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/layout/Header/Header.tsx | 2 +- frontend/src/constants/routes.ts | 2 +- frontend/src/hooks/useMyGameStatus.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/layout/Header/Header.tsx b/frontend/src/components/layout/Header/Header.tsx index 7f0bec4d..a1c422d7 100644 --- a/frontend/src/components/layout/Header/Header.tsx +++ b/frontend/src/components/layout/Header/Header.tsx @@ -19,7 +19,7 @@ const Header = ({ title }: HeaderProps) => { const { roomId } = useParams(); const isRoundResultPage = location.pathname === ROUTES.roundResult(Number(roomId)); - const isFinalPage = location.pathname === ROUTES.gameResult; + const isFinalPage = location.pathname === ROUTES.gameResult(Number(roomId)); const isNicknamePage = location.pathname.startsWith(ROUTES.nickname); if (isFinalPage) { diff --git a/frontend/src/constants/routes.ts b/frontend/src/constants/routes.ts index b3ac59ea..d48c38f8 100644 --- a/frontend/src/constants/routes.ts +++ b/frontend/src/constants/routes.ts @@ -5,6 +5,6 @@ export const ROUTES = { game: (roomId: number) => `/${roomId}/game`, roundResult: (roomId: number) => `/${roomId}/round/result`, roundResultVote: '/round/result/vote', - gameResult: '/game/result', + gameResult: (roomId: number) => `/${roomId}/game/result`, roundResultStatus: (roomId: number) => `/${roomId}/round/result/status`, } as const; diff --git a/frontend/src/hooks/useMyGameStatus.ts b/frontend/src/hooks/useMyGameStatus.ts index f8f8d0d3..dbbb5d05 100644 --- a/frontend/src/hooks/useMyGameStatus.ts +++ b/frontend/src/hooks/useMyGameStatus.ts @@ -19,7 +19,7 @@ const useMyGameStatus = ({ roomId, currentRound }: UseMyGameStatusProps) => { }); const goToGameResult = () => { - navigate(ROUTES.gameResult); + navigate(ROUTES.gameResult(Number(roomId))); }; const goToNextRound = () => { From 78c23231081331742c8f2813fed2f5f4d9faea6c Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 17:48:05 +0900 Subject: [PATCH 0625/1013] =?UTF-8?q?refactor:=20default=20=EA=B0=92?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=84=A4=EC=A0=95=EB=90=9C=20=EB=B6=88?= =?UTF-8?q?=ED=95=84=EC=9A=94=ED=95=9C=20=EC=BD=94=EB=93=9C=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useMyGameStatusQuery.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/hooks/useMyGameStatusQuery.ts b/frontend/src/hooks/useMyGameStatusQuery.ts index 43339981..67b95e0f 100644 --- a/frontend/src/hooks/useMyGameStatusQuery.ts +++ b/frontend/src/hooks/useMyGameStatusQuery.ts @@ -21,7 +21,6 @@ const useMyGameStatusQuery = ({ roomId, currentRound }: useMyGameStatusQueryProp }); }, enabled: !!currentRound, - staleTime: 0, refetchInterval: 1000, }); From 3adf7d0c89185739db6905556a3070b5970c81a7 Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 17:51:34 +0900 Subject: [PATCH 0626/1013] =?UTF-8?q?refactor:=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=EA=B0=80=20=EC=97=86=EB=8A=94=20=EA=B2=BD=EC=9A=B0=20?= =?UTF-8?q?null=EC=9D=B4=20=EC=95=84=EB=8B=8C=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=EA=B0=80=20=EC=97=86=EC=9D=8C=EC=9D=84=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=EC=9E=90=EC=97=90=EA=B2=8C=20=EC=95=8C=EB=A0=A4?= =?UTF-8?q?=EC=A3=BC=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OptionParticipantsContainer/OptionParticipantsContainer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx index 14be9b19..ab2afbb3 100644 --- a/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx +++ b/frontend/src/components/OptionParticipantsContainer/OptionParticipantsContainer.tsx @@ -23,7 +23,7 @@ const OptionParticipantsContainer = () => { useMyGameStatus({ roomId: Number(roomId), currentRound }); if (!groupRoundResult) { - return null; + return
    데이터가 없습니다
    ; } return ( From 44fa2a342e22b6401d03ec61abae644eb4b2e348 Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 17:58:56 +0900 Subject: [PATCH 0627/1013] =?UTF-8?q?chore:=20cypress=20=EC=84=A4=EC=B9=98?= =?UTF-8?q?=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/package-lock.json | 1200 +++++++++++++++++++++++++++++++++++- frontend/package.json | 1 + 2 files changed, 1197 insertions(+), 4 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 6ddf923f..1fe0d99e 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -45,6 +45,7 @@ "@typescript-eslint/parser": "^7.16.0", "babel-loader": "^9.1.3", "core-js": "^3.37.1", + "cypress": "^13.13.2", "dotenv": "^16.4.5", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", @@ -2095,6 +2096,16 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@csstools/css-parser-algorithms": { "version": "2.7.1", "dev": true, @@ -2177,6 +2188,83 @@ "postcss-selector-parser": "^6.0.13" } }, + "node_modules/@cypress/request": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.1.tgz", + "integrity": "sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "http-signature": "~1.3.6", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "performance-now": "^2.1.0", + "qs": "6.10.4", + "safe-buffer": "^5.1.2", + "tough-cookie": "^4.1.3", + "tunnel-agent": "^0.6.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@cypress/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/@cypress/request/node_modules/qs": { + "version": "6.10.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.4.tgz", + "integrity": "sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@cypress/xvfb": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", + "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", + "dev": true, + "dependencies": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + } + }, + "node_modules/@cypress/xvfb/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "dev": true, @@ -6164,6 +6252,18 @@ "@types/send": "*" } }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", + "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", + "dev": true + }, + "node_modules/@types/sizzle": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.8.tgz", + "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==", + "dev": true + }, "node_modules/@types/sockjs": { "version": "0.3.36", "dev": true, @@ -6223,6 +6323,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "7.16.0", "dev": true, @@ -6745,6 +6855,19 @@ "node": ">= 6.0.0" } }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ajv": { "version": "6.12.6", "dev": true, @@ -6804,6 +6927,15 @@ "ajv": "^6.9.1" } }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-escapes": { "version": "6.2.1", "dev": true, @@ -6856,6 +6988,26 @@ "node": ">= 8" } }, + "node_modules/arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/argparse": { "version": "2.0.1", "dev": true, @@ -7035,6 +7187,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, "node_modules/assertion-error": { "version": "1.1.0", "dev": true, @@ -7068,11 +7238,26 @@ "node": ">=8" } }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "dev": true + }, "node_modules/asynckit": { "version": "0.4.0", "dev": true, "license": "MIT" }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/available-typed-arrays": { "version": "1.0.7", "dev": true, @@ -7087,6 +7272,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.1.tgz", + "integrity": "sha512-u5w79Rd7SU4JaIlA/zFqG+gOiuq25q5VLyZ8E+ijJeILuTxVzZgp2CaGw/UTw6pXYN9XMO9yiqj/nEHmhTG5CA==", + "dev": true + }, "node_modules/axe-core": { "version": "4.9.1", "dev": true, @@ -7420,6 +7620,15 @@ "dev": true, "license": "MIT" }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, "node_modules/big.js": { "version": "5.2.2", "dev": true, @@ -7449,6 +7658,18 @@ "readable-stream": "^3.4.0" } }, + "node_modules/blob-util": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", + "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", + "dev": true + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, "node_modules/body-parser": { "version": "1.20.2", "dev": true, @@ -7592,6 +7813,15 @@ "ieee754": "^1.1.13" } }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "dev": true, @@ -7619,6 +7849,15 @@ "node": ">= 0.8" } }, + "node_modules/cachedir": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", + "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/call-bind": { "version": "1.0.7", "dev": true, @@ -7688,6 +7927,12 @@ "node": ">=4" } }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, "node_modules/chai": { "version": "4.4.1", "dev": true, @@ -7753,6 +7998,15 @@ "node": "*" } }, + "node_modules/check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/chokidar": { "version": "3.6.0", "dev": true, @@ -7852,6 +8106,15 @@ "node": ">= 10.0" } }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/cli-cursor": { "version": "4.0.0", "dev": true, @@ -7877,6 +8140,41 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-table3/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/cli-table3/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/cli-truncate": { "version": "4.0.0", "dev": true, @@ -8100,6 +8398,15 @@ "dev": true, "license": "ISC" }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/commondir": { "version": "1.0.1", "dev": true, @@ -8506,11 +8813,419 @@ "version": "3.1.3", "license": "MIT" }, + "node_modules/cypress": { + "version": "13.13.2", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.13.2.tgz", + "integrity": "sha512-PvJQU33933NvS1StfzEb8/mu2kMy4dABwCF+yd5Bi7Qly1HOVf+Bufrygee/tlmty/6j5lX+KIi8j9Q3JUMbhA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@cypress/request": "^3.0.1", + "@cypress/xvfb": "^1.2.4", + "@types/sinonjs__fake-timers": "8.1.1", + "@types/sizzle": "^2.3.2", + "arch": "^2.2.0", + "blob-util": "^2.0.2", + "bluebird": "^3.7.2", + "buffer": "^5.7.1", + "cachedir": "^2.3.0", + "chalk": "^4.1.0", + "check-more-types": "^2.24.0", + "cli-cursor": "^3.1.0", + "cli-table3": "~0.6.1", + "commander": "^6.2.1", + "common-tags": "^1.8.0", + "dayjs": "^1.10.4", + "debug": "^4.3.4", + "enquirer": "^2.3.6", + "eventemitter2": "6.4.7", + "execa": "4.1.0", + "executable": "^4.1.1", + "extract-zip": "2.0.1", + "figures": "^3.2.0", + "fs-extra": "^9.1.0", + "getos": "^3.2.1", + "is-ci": "^3.0.1", + "is-installed-globally": "~0.4.0", + "lazy-ass": "^1.6.0", + "listr2": "^3.8.3", + "lodash": "^4.17.21", + "log-symbols": "^4.0.0", + "minimist": "^1.2.8", + "ospath": "^1.2.2", + "pretty-bytes": "^5.6.0", + "process": "^0.11.10", + "proxy-from-env": "1.0.0", + "request-progress": "^3.0.0", + "semver": "^7.5.3", + "supports-color": "^8.1.1", + "tmp": "~0.2.3", + "untildify": "^4.0.0", + "yauzl": "^2.10.0" + }, + "bin": { + "cypress": "bin/cypress" + }, + "engines": { + "node": "^16.0.0 || ^18.0.0 || >=20.0.0" + } + }, + "node_modules/cypress/node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cypress/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/cypress/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/cypress/node_modules/chalk/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/cypress/node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cypress/node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cypress/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/cypress/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/cypress/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/cypress/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/cypress/node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/cypress/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/cypress/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cypress/node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/cypress/node_modules/listr2": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", + "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", + "dev": true, + "dependencies": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.1", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, + "node_modules/cypress/node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cypress/node_modules/log-update/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/cypress/node_modules/log-update/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cypress/node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cypress/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cypress/node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cypress/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cypress/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cypress/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "dev": true, "license": "BSD-2-Clause" }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/data-urls": { "version": "3.0.2", "dev": true, @@ -8572,6 +9287,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/dayjs": { + "version": "1.11.12", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.12.tgz", + "integrity": "sha512-Rt2g+nTbLlDWZTwwrIXjy9MeiZmSDI375FvZs72ngxx8PDC6YXOeR3q5LAuPzjZQxhiWdRKac7RKV+YyQYfYIg==", + "dev": true + }, "node_modules/debug": { "version": "4.3.5", "license": "MIT", @@ -8964,6 +9685,16 @@ "dev": true, "license": "MIT" }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, "node_modules/ee-first": { "version": "1.1.1", "dev": true, @@ -9006,6 +9737,15 @@ "node": ">= 0.8" } }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/endent": { "version": "2.1.0", "dev": true, @@ -9024,13 +9764,26 @@ "node_modules/enhanced-resolve": { "version": "5.17.0", "dev": true, - "license": "MIT", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=10.13.0" + "node": ">=8.6" } }, "node_modules/entities": { @@ -10132,6 +10885,12 @@ "node": ">= 0.6" } }, + "node_modules/eventemitter2": { + "version": "6.4.7", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", + "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==", + "dev": true + }, "node_modules/eventemitter3": { "version": "4.0.7", "dev": true, @@ -10167,6 +10926,27 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "dependencies": { + "pify": "^2.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/executable/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/exit": { "version": "0.1.2", "dev": true, @@ -10243,6 +11023,56 @@ "dev": true, "license": "MIT" }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "dev": true, @@ -10326,6 +11156,30 @@ "walk-up-path": "^3.0.1" } }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "dev": true, @@ -10656,6 +11510,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/fork-ts-checker-webpack-plugin": { "version": "9.0.2", "dev": true, @@ -11022,6 +11885,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/getos": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", + "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", + "dev": true, + "dependencies": { + "async": "^3.2.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, "node_modules/giget": { "version": "1.2.3", "dev": true, @@ -11080,6 +11961,30 @@ "dev": true, "license": "BSD-2-Clause" }, + "node_modules/global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "dev": true, + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-dirs/node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/global-modules": { "version": "2.0.0", "dev": true, @@ -11623,6 +12528,20 @@ } } }, + "node_modules/http-signature": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", + "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^2.0.2", + "sshpk": "^1.14.1" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.1", "dev": true, @@ -11924,6 +12843,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, "node_modules/is-core-module": { "version": "2.14.0", "license": "MIT", @@ -12056,6 +12987,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-interactive": { "version": "1.0.0", "dev": true, @@ -12252,6 +13199,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, "node_modules/is-unicode-supported": { "version": "0.1.0", "dev": true, @@ -12332,6 +13285,12 @@ "node": ">=0.10.0" } }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "dev": true, @@ -14077,6 +15036,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, "node_modules/jscodeshift": { "version": "0.15.2", "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.15.2.tgz", @@ -14251,6 +15216,12 @@ "version": "2.3.1", "license": "MIT" }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "dev": true, @@ -14261,6 +15232,12 @@ "dev": true, "license": "MIT" }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, "node_modules/json5": { "version": "2.2.3", "dev": true, @@ -14283,6 +15260,21 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsprim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", + "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "dev": true, @@ -14351,6 +15343,15 @@ "shell-quote": "^1.8.1" } }, + "node_modules/lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", + "dev": true, + "engines": { + "node": "> 0.8" + } + }, "node_modules/leven": { "version": "3.1.0", "dev": true, @@ -14707,6 +15708,12 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "dev": true + }, "node_modules/lodash.truncate": { "version": "4.4.2", "dev": true, @@ -15984,6 +16991,12 @@ "node": ">=8" } }, + "node_modules/ospath": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", + "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", + "dev": true + }, "node_modules/outvariant": { "version": "1.4.3", "dev": true, @@ -16014,6 +17027,21 @@ "node": ">=8" } }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-retry": { "version": "6.2.0", "dev": true, @@ -16184,6 +17212,18 @@ "node": "*" } }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true + }, "node_modules/picocolors": { "version": "1.0.1", "license": "ISC" @@ -16439,6 +17479,18 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/pretty-error": { "version": "4.0.0", "dev": true, @@ -16532,11 +17584,27 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", + "dev": true + }, "node_modules/psl": { "version": "1.9.0", "dev": true, "license": "MIT" }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "dev": true, @@ -17015,6 +18083,15 @@ "strip-ansi": "^6.0.1" } }, + "node_modules/request-progress": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", + "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", + "dev": true, + "dependencies": { + "throttleit": "^1.0.0" + } + }, "node_modules/require-directory": { "version": "2.1.1", "dev": true, @@ -17173,6 +18250,15 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-array-concat": { "version": "1.1.2", "dev": true, @@ -17650,6 +18736,31 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/stack-utils": { "version": "2.0.6", "dev": true, @@ -18885,6 +19996,21 @@ "tslib": "^2" } }, + "node_modules/throttleit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", + "integrity": "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, "node_modules/thunky": { "version": "1.1.0", "dev": true, @@ -18903,6 +20029,15 @@ "node": ">=14.0.0" } }, + "node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, + "engines": { + "node": ">=14.14" + } + }, "node_modules/tmpl": { "version": "1.0.5", "dev": true, @@ -19141,11 +20276,29 @@ "dev": true, "license": "0BSD" }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, "node_modules/tween-functions": { "version": "1.2.0", "dev": true, "license": "BSD" }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, "node_modules/type-check": { "version": "0.4.0", "dev": true, @@ -19432,6 +20585,15 @@ "node": ">=14.0.0" } }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.0", "dev": true, @@ -19565,6 +20727,26 @@ "node": ">= 0.8" } }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + }, "node_modules/w3c-xmlserializer": { "version": "4.0.0", "dev": true, @@ -20356,6 +21538,16 @@ "node": ">=8" } }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "node_modules/yocto-queue": { "version": "1.1.1", "dev": true, diff --git a/frontend/package.json b/frontend/package.json index 8597f6fb..f6805d6e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -55,6 +55,7 @@ "@typescript-eslint/parser": "^7.16.0", "babel-loader": "^9.1.3", "core-js": "^3.37.1", + "cypress": "^13.13.2", "dotenv": "^16.4.5", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From 973cdb7c730fd801dc856f4dc6e42d444bf0d709 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Wed, 7 Aug 2024 19:15:06 +0900 Subject: [PATCH 0628/1013] =?UTF-8?q?build:=20sentry=20dependencies?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EB=8F=99=20#137?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/package-lock.json | 123 +++++++++++++++++-------------------- frontend/package.json | 2 +- 2 files changed, 58 insertions(+), 67 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index dd643e53..60580629 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -10,6 +10,7 @@ "license": "ISC", "dependencies": { "@emotion/react": "^11.11.4", + "@sentry/react": "^8.24.0", "@tanstack/react-query": "^5.51.1", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -25,7 +26,6 @@ "@chromatic-com/storybook": "^1.6.1", "@emotion/babel-plugin": "^11.12.0", "@emotion/babel-preset-css-prop": "^11.11.0", - "@sentry/react": "^8.23.0", "@sentry/webpack-plugin": "^2.22.0", "@storybook/addon-essentials": "^8.2.2", "@storybook/addon-interactions": "^8.2.2", @@ -3969,58 +3969,54 @@ } }, "node_modules/@sentry-internal/browser-utils": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.23.0.tgz", - "integrity": "sha512-PQ0S7MRP8REo1iF+qZHNuLF+Qh7fuULA56tw0CRzTO1j7y87hQz9EJ8L0fBewuOitFQhSrZ7bfjJt9lIDTMfTQ==", - "dev": true, + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.24.0.tgz", + "integrity": "sha512-U5dVZ4JM+UeN3YWBUHZcNLF038C3ccTTsTICIw+zfCQbpPhPms8DOEDVpd0So18XoNDzYmLo07hC1BwByRAfGw==", "dependencies": { - "@sentry/core": "8.23.0", - "@sentry/types": "8.23.0", - "@sentry/utils": "8.23.0" + "@sentry/core": "8.24.0", + "@sentry/types": "8.24.0", + "@sentry/utils": "8.24.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/feedback": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.23.0.tgz", - "integrity": "sha512-xDwUohTOAW2Vwv9Vc6T2k8s8lvmQQck0YLmiafLbM2uqfyd2g3azRmWYQIsASSru2KdMYXgoLhZ/A0FGUlte9w==", - "dev": true, + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.24.0.tgz", + "integrity": "sha512-0tWRp8SOSTSPTViRJnB6+HHixFgkEWjKPciuLsAZkobRhi+VVedPj3zVztORy5AvARGr6AgyVSdnviilcrKl6g==", "dependencies": { - "@sentry/core": "8.23.0", - "@sentry/types": "8.23.0", - "@sentry/utils": "8.23.0" + "@sentry/core": "8.24.0", + "@sentry/types": "8.24.0", + "@sentry/utils": "8.24.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.23.0.tgz", - "integrity": "sha512-3HeLMgtJoQvX6FHw2kzo3vlLElMyNWLIaJl5BtUzVnQw1fEoV8R3Mwrn02nwW3IFIPUv0O+xn/Icx6InenfBqQ==", - "dev": true, + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.24.0.tgz", + "integrity": "sha512-+3d+3Ln7iDOZo2wOBv7EWojVHigEskjKsz8vR3WFdxYyue8e3zPQ/xg/t9A6BtEVRPQsEyhM3oN6LyjqFv2nfg==", "dependencies": { - "@sentry-internal/browser-utils": "8.23.0", - "@sentry/core": "8.23.0", - "@sentry/types": "8.23.0", - "@sentry/utils": "8.23.0" + "@sentry-internal/browser-utils": "8.24.0", + "@sentry/core": "8.24.0", + "@sentry/types": "8.24.0", + "@sentry/utils": "8.24.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay-canvas": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.23.0.tgz", - "integrity": "sha512-Guqy+Ae0ZdNNBFnkHFT6bbyzUcW/8liTUZUQS3fdHkaav4qKIPAdMGob2e09GKczf5zSaaobiChsMpaXMLHlMA==", - "dev": true, + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.24.0.tgz", + "integrity": "sha512-MI+j9tUab1d5oer2xKQ2lxdXSzBeZ1DF2dwlVxQDOfSAQqRfZJpmLcmSPb6M+GJsf2xHg6n4dAQvWQuM0qGQPQ==", "dependencies": { - "@sentry-internal/replay": "8.23.0", - "@sentry/core": "8.23.0", - "@sentry/types": "8.23.0", - "@sentry/utils": "8.23.0" + "@sentry-internal/replay": "8.24.0", + "@sentry/core": "8.24.0", + "@sentry/types": "8.24.0", + "@sentry/utils": "8.24.0" }, "engines": { "node": ">=14.18" @@ -4036,18 +4032,17 @@ } }, "node_modules/@sentry/browser": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.23.0.tgz", - "integrity": "sha512-KyoFp4et+y26wn99sXRp6+vme1Gha8DPQo2DbO64IR49tqkBXr8/D1QkpV3rqkPdttH7fefFNvaM4h3+9d6OtQ==", - "dev": true, + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.24.0.tgz", + "integrity": "sha512-WdCLUoMAE0ZWsZDb3G/FQI5YgkH59VVEpnPqrWI08m2KuqLz8eU724JZvNzaDv/L2yzksgS4HDDUXkNRzDeCrQ==", "dependencies": { - "@sentry-internal/browser-utils": "8.23.0", - "@sentry-internal/feedback": "8.23.0", - "@sentry-internal/replay": "8.23.0", - "@sentry-internal/replay-canvas": "8.23.0", - "@sentry/core": "8.23.0", - "@sentry/types": "8.23.0", - "@sentry/utils": "8.23.0" + "@sentry-internal/browser-utils": "8.24.0", + "@sentry-internal/feedback": "8.24.0", + "@sentry-internal/replay": "8.24.0", + "@sentry-internal/replay-canvas": "8.24.0", + "@sentry/core": "8.24.0", + "@sentry/types": "8.24.0", + "@sentry/utils": "8.24.0" }, "engines": { "node": ">=14.18" @@ -4362,28 +4357,26 @@ } }, "node_modules/@sentry/core": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.23.0.tgz", - "integrity": "sha512-o0tHpxwi5WxjaQPtY+BPkG8FliM4QB91QKoi2QclWvR9t9jUgMWZ4ikziybNiKICZRXtN9B6wSBWlPVWfsiN6A==", - "dev": true, + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.24.0.tgz", + "integrity": "sha512-nyy7po78Ef5KNzehHJCCyLGGR/FceHyw2IRzDQUVD6M4tos8G1OML1gcnALChWhyeq1SIoDsC1ofxFlbkIWuog==", "dependencies": { - "@sentry/types": "8.23.0", - "@sentry/utils": "8.23.0" + "@sentry/types": "8.24.0", + "@sentry/utils": "8.24.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry/react": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@sentry/react/-/react-8.23.0.tgz", - "integrity": "sha512-Q+xuAySlQDvp0YWcxH4BtaDqA7On+ZvsZYcp0rFe1DE+e3/pyCqPae9dBCI+sQYPqnLgVoz05ANWorzSbpk08Q==", - "dev": true, - "dependencies": { - "@sentry/browser": "8.23.0", - "@sentry/core": "8.23.0", - "@sentry/types": "8.23.0", - "@sentry/utils": "8.23.0", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@sentry/react/-/react-8.24.0.tgz", + "integrity": "sha512-UaNmGEtYUFMoE1lKlsedOYGvQX72/A+/CiDg5umQwwS33XfGY4geh3zMo3jjEKTjhR1T5gofBz74sXnTCyrW4A==", + "dependencies": { + "@sentry/browser": "8.24.0", + "@sentry/core": "8.24.0", + "@sentry/types": "8.24.0", + "@sentry/utils": "8.24.0", "hoist-non-react-statics": "^3.3.2" }, "engines": { @@ -4394,21 +4387,19 @@ } }, "node_modules/@sentry/types": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.23.0.tgz", - "integrity": "sha512-oJbZ04chsz3Gqro3GJuAAcEsJ7RVjk3k4TvAMxmhN5tQUqwvKFtvWjfskcF75ECzY+8Qge6PI7eXoibkhjx8sg==", - "dev": true, + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.24.0.tgz", + "integrity": "sha512-5QWXARoFrvTvnS19ip+ha0x4nWIv/RvoCTnqCsgrNTjypbk1+KMSMQQhGMo8OuEBFhdGyTs1BqfxVV82URHh3w==", "engines": { "node": ">=14.18" } }, "node_modules/@sentry/utils": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.23.0.tgz", - "integrity": "sha512-g+rkk+vFQnAz7xHGUTHXybA9qFdp1mtv3JGXtFKlLxPm8bKpzbBlJA3FiX4E7ai/Ksbv0N+K7c5fDth3LX3wAA==", - "dev": true, + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.24.0.tgz", + "integrity": "sha512-AGo5PldxCJYn3g0IYXeBkeALNa+NieJaaCDpYyzrKAFdxoA6Qp+Z/wmN9m5BYZ9eHx9N+xMOoz2aIh4hG48VbQ==", "dependencies": { - "@sentry/types": "8.23.0" + "@sentry/types": "8.24.0" }, "engines": { "node": ">=14.18" diff --git a/frontend/package.json b/frontend/package.json index 3dd81aec..8467b409 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -20,6 +20,7 @@ "license": "ISC", "dependencies": { "@emotion/react": "^11.11.4", + "@sentry/react": "^8.24.0", "@tanstack/react-query": "^5.51.1", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -35,7 +36,6 @@ "@chromatic-com/storybook": "^1.6.1", "@emotion/babel-plugin": "^11.12.0", "@emotion/babel-preset-css-prop": "^11.11.0", - "@sentry/react": "^8.23.0", "@sentry/webpack-plugin": "^2.22.0", "@storybook/addon-essentials": "^8.2.2", "@storybook/addon-interactions": "^8.2.2", From 68c3f297e74ba00f39095eeb03e51d5b8911cd1e Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 19:43:32 +0900 Subject: [PATCH 0629/1013] =?UTF-8?q?refactor:=20=EA=B2=8C=EC=9E=84=20?= =?UTF-8?q?=EB=8C=80=EA=B8=B0=20=ED=99=94=EB=A9=B4=20=EB=9D=BC=EC=9A=B0?= =?UTF-8?q?=ED=84=B0=20=EC=88=98=EC=A0=95=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/common/FinalButton/FinalButton.tsx | 7 +++++-- frontend/src/constants/routes.ts | 2 +- frontend/src/pages/NicknamePage/useMakeOrEnterRoom.ts | 5 +++-- frontend/src/router/index.tsx | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/frontend/src/components/common/FinalButton/FinalButton.tsx b/frontend/src/components/common/FinalButton/FinalButton.tsx index e3fd781e..5d6b9794 100644 --- a/frontend/src/components/common/FinalButton/FinalButton.tsx +++ b/frontend/src/components/common/FinalButton/FinalButton.tsx @@ -1,13 +1,16 @@ -import { useNavigate } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router-dom'; import Button from '../Button/Button'; import { bottomButtonLayout } from '../Button/Button.styled'; +import { ROUTES } from '@/constants/routes'; + const FinalButton = () => { + const { roomId } = useParams(); const navigate = useNavigate(); const goToHome = () => { - navigate('/ready'); + navigate(ROUTES.ready(Number(roomId))); }; return ( diff --git a/frontend/src/constants/routes.ts b/frontend/src/constants/routes.ts index d48c38f8..7dce3c72 100644 --- a/frontend/src/constants/routes.ts +++ b/frontend/src/constants/routes.ts @@ -1,7 +1,7 @@ export const ROUTES = { main: '/', nickname: '/nickname', - ready: '/ready', + ready: (roomId: number) => `/${roomId}/ready`, game: (roomId: number) => `/${roomId}/game`, roundResult: (roomId: number) => `/${roomId}/round/result`, roundResultVote: '/round/result/vote', diff --git a/frontend/src/pages/NicknamePage/useMakeOrEnterRoom.ts b/frontend/src/pages/NicknamePage/useMakeOrEnterRoom.ts index c56862a9..19c38310 100644 --- a/frontend/src/pages/NicknamePage/useMakeOrEnterRoom.ts +++ b/frontend/src/pages/NicknamePage/useMakeOrEnterRoom.ts @@ -4,6 +4,7 @@ import { useNavigate, useParams } from 'react-router-dom'; import { useRecoilValue } from 'recoil'; import { enterRoom, createRoom } from '@/apis/room'; +import { ROUTES } from '@/constants/routes'; import { memberInfoState } from '@/recoil/atom'; import { RoomIdAndMember } from '@/types/room'; import { createRandomNickname } from '@/utils/nickname'; @@ -19,7 +20,7 @@ export const useMakeOrEnterRoom = () => { const createRoomMutation = useMutation({ mutationFn: createRoom, onSuccess: (data) => { - navigate(`/ready/${data.roomId}`); + navigate(ROUTES.ready(Number(data.roomId))); }, onError: (error: Error) => {}, }); @@ -31,7 +32,7 @@ export const useMakeOrEnterRoom = () => { >({ mutationFn: ({ nickname, roomId }) => enterRoom(roomId, nickname), onSuccess: () => { - navigate(`/ready/${roomId}`); + navigate(ROUTES.ready(Number(roomId))); }, onError: (error: Error) => {}, }); diff --git a/frontend/src/router/index.tsx b/frontend/src/router/index.tsx index 9376bf99..e04b17e0 100644 --- a/frontend/src/router/index.tsx +++ b/frontend/src/router/index.tsx @@ -28,7 +28,7 @@ export const router = createBrowserRouter([ element: , }, { - path: 'ready/:roomId', + path: ':roomId/ready', element: , }, { From b7daeaa3f9df4e5c2d758ce9e1022916dd406305 Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 19:44:39 +0900 Subject: [PATCH 0630/1013] =?UTF-8?q?refactor:=20=EB=B0=A9=20=EB=A9=A4?= =?UTF-8?q?=EB=B2=84=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20msw=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/mocks/handlers/index.ts | 3 ++- frontend/src/mocks/handlers/roomHandler.ts | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 frontend/src/mocks/handlers/roomHandler.ts diff --git a/frontend/src/mocks/handlers/index.ts b/frontend/src/mocks/handlers/index.ts index 05552ea8..c2ed13cc 100644 --- a/frontend/src/mocks/handlers/index.ts +++ b/frontend/src/mocks/handlers/index.ts @@ -1,4 +1,5 @@ import { contentHandler } from './balanceContentHandler'; +import { roomHandler } from './roomHandler'; import { voteHandler } from './voteHandler'; -export const handlers = [...contentHandler, ...voteHandler]; +export const handlers = [...contentHandler, ...voteHandler, ...roomHandler]; diff --git a/frontend/src/mocks/handlers/roomHandler.ts b/frontend/src/mocks/handlers/roomHandler.ts new file mode 100644 index 00000000..b2e5186f --- /dev/null +++ b/frontend/src/mocks/handlers/roomHandler.ts @@ -0,0 +1,11 @@ +import { http, HttpResponse } from 'msw'; + +import ROOM_INFO from '../data/roomInfo.json'; + +import { MOCK_API_URL } from '@/constants/url'; + +const getRoomMemberHandler = () => { + return HttpResponse.json(ROOM_INFO); +}; + +export const roomHandler = [http.get(MOCK_API_URL.roomMembers, getRoomMemberHandler)]; From ee5dfabcaef0eb0ca69bcd4366adf9148023e8e1 Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 19:45:17 +0900 Subject: [PATCH 0631/1013] =?UTF-8?q?refactor:=20=EB=A9=A4=EB=B2=84=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=EA=B0=80=20=EC=97=86=EB=8A=94=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=EB=A5=BC=20=EC=B2=98=EB=A6=AC=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadyMembersContainer/ReadyMembersContainer.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx index 8cc76c7a..366e77f9 100644 --- a/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx +++ b/frontend/src/components/ReadyMembersContainer/ReadyMembersContainer.tsx @@ -16,6 +16,10 @@ import { RoomMembers } from '@/types/room'; interface ReadyMembersContainerProps extends RoomMembers {} const ReadyMembersContainer = ({ members }: ReadyMembersContainerProps) => { + if (!members) { + return
    데이터가 없습니다.
    ; + } + return (

    총 인원 {members.length}명

    From 7a5fe699d5bd5d505d6c462f3c0a0a414007ebc3 Mon Sep 17 00:00:00 2001 From: useon Date: Wed, 7 Aug 2024 22:31:14 +0900 Subject: [PATCH 0632/1013] =?UTF-8?q?refactor:=20=EA=B2=8C=EC=9E=84=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B4=EB=93=9C=20=EC=A2=85=EB=A3=8C=20=EB=B0=8F=20?= =?UTF-8?q?=EA=B2=8C=EC=9E=84=20=EC=A2=85=EB=A3=8C=20=EC=97=AC=EB=B6=80?= =?UTF-8?q?=EB=A5=BC=20=ED=99=95=EC=9D=B8=ED=95=98=EB=8A=94=20api=20?= =?UTF-8?q?=EC=A3=BC=EC=86=8C=20=EC=88=98=EC=A0=95=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/constants/url.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/constants/url.ts b/frontend/src/constants/url.ts index e3647522..ec2adfe5 100644 --- a/frontend/src/constants/url.ts +++ b/frontend/src/constants/url.ts @@ -8,7 +8,7 @@ export const API_URL = { `${BASE_URL}/api/balances/rooms/${roomId}/contents/${contentId}/vote-result`, moveNextRound: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/next-round`, myGameStatus: (roomId: number, round: number) => - `${BASE_URL}/api/balances/rooms/${roomId}?round=${round}`, + `${BASE_URL}/api/balances/rooms/${roomId}/round-finished?round=${round}`, finalResult: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/final`, room: `${BASE_URL}/api/balances/rooms`, enterRoom: (roomId: number) => `${BASE_URL}/api/balances/rooms/${roomId}/members`, @@ -21,7 +21,7 @@ export const MOCK_API_URL = { balanceContent: `${BASE_URL}/api/balances/rooms/:roomId/content`, vote: `${BASE_URL}/api/balances/rooms/:roomId/contents/:contentId/votes`, roundVoteResult: `${BASE_URL}/api/balances/rooms/:roomId/contents/:contentId/vote-result`, - myGameStatus: `${BASE_URL}/api/balances/rooms/:roomId?round=:round`, + myGameStatus: `${BASE_URL}/api/balances/rooms/:roomId/round-finished?round=:round`, moveNextRound: `${BASE_URL}/api/balances/rooms/:roomId/next-round`, finalResult: `${BASE_URL}/api/balances/rooms/:roomId/final`, room: `${BASE_URL}/api/balances/rooms`, From 82de931eca882ea2c3c6bf67d5481b292dcb1349 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Wed, 7 Aug 2024 22:37:24 +0900 Subject: [PATCH 0633/1013] =?UTF-8?q?chore:=20storybook=20=EB=B0=B0?= =?UTF-8?q?=ED=8F=AC=20=EC=8A=A4=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EA=B0=B1?= =?UTF-8?q?=EC=8B=A0=20#147?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/fe-cd-storybook.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/fe-cd-storybook.yml b/.github/workflows/fe-cd-storybook.yml index 765f5fb9..594b1f69 100644 --- a/.github/workflows/fe-cd-storybook.yml +++ b/.github/workflows/fe-cd-storybook.yml @@ -50,8 +50,19 @@ jobs: repo: context.repo.repo, pull_number: context.issue.number }); + const body = pr.data.body; - const newBody = body + "\n\n" + "## 🌸 Storybook 배포 주소 \n\n"+ "> https://woowacourse-teams.github.io/2024-ddangkong/storybook/"; + const storybookUrl = "## 🌸 Storybook 배포 주소 \n\n> https://woowacourse-teams.github.io/2024-ddangkong/storybook/"; + + if (!body.includes(storybookUrl)) { + const newBody = body + "\n\n" + storybookUrl; + await github.rest.pulls.update({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number, + body: newBody + }); + } await github.rest.pulls.update({ owner: context.repo.owner, repo: context.repo.repo, From d2520cc5d967db76108e3398a7a366f05b0070ce Mon Sep 17 00:00:00 2001 From: Nam Gi Beom Date: Wed, 7 Aug 2024 23:11:16 +0900 Subject: [PATCH 0634/1013] =?UTF-8?q?fix:=20=EB=B0=B1=20=EC=8A=AC=EB=9E=98?= =?UTF-8?q?=EC=8B=9C=20=EC=B6=94=EA=B0=80=20#156?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/be-cd-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/be-cd-dev.yml b/.github/workflows/be-cd-dev.yml index 087d55c2..658e869a 100644 --- a/.github/workflows/be-cd-dev.yml +++ b/.github/workflows/be-cd-dev.yml @@ -99,5 +99,5 @@ jobs: - name: Run new Docker container run: | docker run -d -p 443:8080 --name $CONTAINER_NAME \ - -v /home/ubuntu/app-logs:/logs + -v /home/ubuntu/app-logs:/logs \ $DOCKER_REPOSITORY_NAME:latest From 3bcef8a579c336ec0d853e430587ba55113c8546 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 8 Aug 2024 00:31:27 +0900 Subject: [PATCH 0635/1013] =?UTF-8?q?design:=20PC=20=EA=B8=B0=EC=A4=80=20?= =?UTF-8?q?=EB=84=88=EB=B9=84=EB=A5=BC=20=ED=83=9C=EB=B8=94=EB=A6=BF=20?= =?UTF-8?q?=EB=84=88=EB=B9=84=EC=9D=B8=20768px=EB=A1=9C=20max-width=20?= =?UTF-8?q?=EC=A7=80=EC=A0=95=20#147?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/styles/GlobalStyle.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/frontend/src/styles/GlobalStyle.ts b/frontend/src/styles/GlobalStyle.ts index 92a6ff59..ca3ee9d6 100644 --- a/frontend/src/styles/GlobalStyle.ts +++ b/frontend/src/styles/GlobalStyle.ts @@ -85,8 +85,8 @@ const reset = css` margin: 0; padding: 0; border: 0; - font-size: 100%; font: inherit; + vertical-align: baseline; } @@ -118,10 +118,10 @@ const reset = css` quotes: none; } - blockquote:before, - blockquote:after, - q:before, - q:after { + blockquote::before, + blockquote::after, + q::before, + q::after { content: ''; content: none; } @@ -132,11 +132,12 @@ const reset = css` } button { + padding: 0; border: none; - outline: none; + background-color: inherit; + outline: none; cursor: pointer; - padding: 0; } `; @@ -148,7 +149,7 @@ const GlobalStyle = css` } #root { - width: 32rem; + max-width: 768px; height: 100vh; margin: 0 auto; } From 2e89a347ddd654866c3ae43f20c701d6950d1d61 Mon Sep 17 00:00:00 2001 From: useon Date: Thu, 8 Aug 2024 02:07:40 +0900 Subject: [PATCH 0636/1013] =?UTF-8?q?feat:=20=EB=B0=A9=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=ED=99=94=20api=20=EC=97=B0=EA=B2=B0=20=EB=B0=8F=20?= =?UTF-8?q?=EC=BB=A4=EC=8A=A4=ED=85=80=20=ED=9B=85=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/room.ts | 11 ++++++++++ .../components/GameResult/GameResult.hook.ts | 11 +++++++--- .../src/components/GameResult/GameResult.tsx | 2 +- .../NextRoundButton/NextRoundButton.tsx | 20 +++++++++---------- frontend/src/constants/url.ts | 1 + 5 files changed, 30 insertions(+), 15 deletions(-) diff --git a/frontend/src/apis/room.ts b/frontend/src/apis/room.ts index bd6b2edd..2fb2bf90 100644 --- a/frontend/src/apis/room.ts +++ b/frontend/src/apis/room.ts @@ -24,6 +24,17 @@ export const createRoom = async (nickname: string): Promise => return data; }; +// 방 초기화하기 +export const resetRoom = async (roomId: number) => { + const res = await fetcher.patch({ + url: API_URL.resetRoom(roomId), + headers: { + 'Content-Type': `application/json`, + }, + }); + return res; +}; + // 방 참여하기 export const enterRoom = async (roomId: number, nickname: string): Promise => { const res = await fetcher.post({ diff --git a/frontend/src/components/GameResult/GameResult.hook.ts b/frontend/src/components/GameResult/GameResult.hook.ts index 7f846641..0953ebdf 100644 --- a/frontend/src/components/GameResult/GameResult.hook.ts +++ b/frontend/src/components/GameResult/GameResult.hook.ts @@ -1,6 +1,7 @@ -import { useQuery, UseQueryResult } from '@tanstack/react-query'; +import { useMutation, useQuery, UseQueryResult } from '@tanstack/react-query'; import { fetchFinalGameResult } from '@/apis/balanceContent'; +import { resetRoom } from '@/apis/room'; import { QUERY_KEYS } from '@/constants/queryKeys'; import { GameFinalResult } from '@/types/balanceContent'; @@ -8,7 +9,7 @@ type GameResultQueryResponse = UseQueryResult & { gameResult?: GameFinalResult[]; }; -const useGameResultQuery = (): GameResultQueryResponse => { +export const useGameResultQuery = (): GameResultQueryResponse => { const gameResultQuery = useQuery({ queryKey: [QUERY_KEYS.gameResult], queryFn: async () => await fetchFinalGameResult(), @@ -17,4 +18,8 @@ const useGameResultQuery = (): GameResultQueryResponse => { return { ...gameResultQuery, gameResult: gameResultQuery.data }; }; -export default useGameResultQuery; +export const useResetRoomMutation = (roomId: number) => { + return useMutation({ + mutationFn: async () => await resetRoom(roomId), + }); +}; diff --git a/frontend/src/components/GameResult/GameResult.tsx b/frontend/src/components/GameResult/GameResult.tsx index 0db449a8..615eaeaf 100644 --- a/frontend/src/components/GameResult/GameResult.tsx +++ b/frontend/src/components/GameResult/GameResult.tsx @@ -1,4 +1,4 @@ -import useGameResultQuery from './GameResult.hook'; +import { useGameResultQuery } from './GameResult.hook'; import { gameResultTitle, gameResultLayout, rankListContainer } from './GameResult.styled'; import FinalButton from '../common/FinalButton/FinalButton'; import GameResultItem from '../GameResultItem/GameResultItem'; diff --git a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx index bd34e888..a25adff2 100644 --- a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx +++ b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx @@ -1,43 +1,41 @@ -import { useNavigate, useParams } from 'react-router-dom'; +import { useParams } from 'react-router-dom'; import { useRecoilValue } from 'recoil'; import useMoveNextRoundMutation from './NextRoundButton.hook'; import Button from '../Button/Button'; import { bottomButtonLayout } from '../Button/Button.styled'; +import { useResetRoomMutation } from '@/components/GameResult/GameResult.hook'; import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; import { memberInfoState } from '@/recoil/atom'; import { Theme } from '@/styles/Theme'; const NextRoundButton = () => { + const goToNextRound = async () => { + await moveNextRound(); + }; + const { roomId } = useParams(); const { balanceContent } = useBalanceContentQuery(); const { mutateAsync: moveNextRound } = useMoveNextRoundMutation(Number(roomId)); const memberInfo = useRecoilValue(memberInfoState); const isLastRound = balanceContent?.currentRound === balanceContent?.totalRound; - const fetchGameResult = () => { - // TODO: 게임 결과 API 추후 연결 - }; - - const fetchNextRound = async () => { - await moveNextRound(); - }; - + const { mutate: resetRoom } = useResetRoomMutation(Number(roomId)); return (
    {memberInfo.isMaster ? (
    ); }; diff --git a/frontend/src/components/common/InviteModal/InviteModal.tsx b/frontend/src/components/common/InviteModal/InviteModal.tsx index 3cf07aef..6b12021d 100644 --- a/frontend/src/components/common/InviteModal/InviteModal.tsx +++ b/frontend/src/components/common/InviteModal/InviteModal.tsx @@ -1,3 +1,5 @@ +import { useParams } from 'react-router-dom'; + import { inviteModalLi, inviteModalHeader, @@ -19,10 +21,12 @@ import CopyIcon from '@/assets/images/copyIcon.png'; interface InviteModalProps { isOpen: boolean; onClose: () => void; - inviteUrl: string; } -const InviteModal = ({ isOpen, onClose, inviteUrl }: InviteModalProps) => { +const InviteModal = ({ isOpen, onClose }: InviteModalProps) => { + const { roomId } = useParams(); + const inviteUrl = `${window.location.origin}${`/nickname/${roomId}`}`; + const { isCopied, copyToClipboard } = useClipBoard(); const handleCopy = () => { From 39f57ac850ef36064189e223f51d505bc99dd686 Mon Sep 17 00:00:00 2001 From: useon Date: Thu, 8 Aug 2024 10:39:49 +0900 Subject: [PATCH 0638/1013] =?UTF-8?q?refactor:=20=EB=B3=B5=EC=82=AC?= =?UTF-8?q?=EA=B0=80=20=EC=99=84=EB=A3=8C=EB=90=98=EB=A9=B4=20state?= =?UTF-8?q?=EA=B0=80=20=EB=B3=80=EA=B2=BD=20=EB=90=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20#132?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/common/InviteModal/useClipBoard.tsx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/common/InviteModal/useClipBoard.tsx b/frontend/src/components/common/InviteModal/useClipBoard.tsx index d2fba4b5..275fa234 100644 --- a/frontend/src/components/common/InviteModal/useClipBoard.tsx +++ b/frontend/src/components/common/InviteModal/useClipBoard.tsx @@ -3,10 +3,16 @@ import { useState } from 'react'; const useClipBoard = () => { const [isCopied, setIsCopied] = useState(false); - const copyToClipboard = async (text: string) => { - await navigator.clipboard.writeText(text); - setIsCopied(true); - setTimeout(() => setIsCopied(false), 2000); + const copyToClipboard = (text: string) => { + navigator.clipboard + .writeText(text) + .then(() => { + setIsCopied(true); + setTimeout(() => setIsCopied(false), 2000); + }) + .catch((error) => { + // TODO: 에러처리 + }); }; return { isCopied, copyToClipboard }; From bec0ccf26c4ad03c0d88af25b03a8748c1bfe265 Mon Sep 17 00:00:00 2001 From: useon Date: Thu, 8 Aug 2024 10:41:41 +0900 Subject: [PATCH 0639/1013] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20args=20=EC=82=AD=EC=A0=9C=20#132?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/common/InviteModal/InviteModal.stories.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontend/src/components/common/InviteModal/InviteModal.stories.tsx b/frontend/src/components/common/InviteModal/InviteModal.stories.tsx index 0db5d900..8aef25d0 100644 --- a/frontend/src/components/common/InviteModal/InviteModal.stories.tsx +++ b/frontend/src/components/common/InviteModal/InviteModal.stories.tsx @@ -40,7 +40,5 @@ export const 초대_모달: Story = { }, args: { isOpen: true, - onClose: fn(), - inviteUrl: '링크입니다', }, }; From a30bfadb1f0d97369893b5a45732486b23c95862 Mon Sep 17 00:00:00 2001 From: useon Date: Thu, 8 Aug 2024 11:24:14 +0900 Subject: [PATCH 0640/1013] =?UTF-8?q?refactor:=20=EB=AA=A8=EB=8B=AC=20?= =?UTF-8?q?=ED=97=A4=EB=8D=94=EC=97=90=20=EC=A0=9C=EB=AA=A9=EA=B3=BC=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=EC=9D=B4=20=EC=9E=88=EB=8A=94=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20=EC=A0=9C=EB=AA=A9=EC=9D=84=20=EC=99=BC=EC=AA=BD=20?= =?UTF-8?q?=EB=98=90=EB=8A=94=20=EA=B0=80=EC=9A=B4=EB=8D=B0=20=EC=9C=84?= =?UTF-8?q?=EC=B9=98=EC=8B=9C=ED=82=A4=EB=8A=94=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0=20#132?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/InviteModal/InviteModal.styled.ts | 17 +---------------- .../common/InviteModal/InviteModal.tsx | 6 ++---- .../components/common/Modal/Modal.stories.tsx | 6 +++--- .../src/components/common/Modal/Modal.styled.ts | 7 ++++++- frontend/src/components/common/Modal/Modal.tsx | 8 ++++++-- 5 files changed, 18 insertions(+), 26 deletions(-) diff --git a/frontend/src/components/common/InviteModal/InviteModal.styled.ts b/frontend/src/components/common/InviteModal/InviteModal.styled.ts index 606dfa96..06b71122 100644 --- a/frontend/src/components/common/InviteModal/InviteModal.styled.ts +++ b/frontend/src/components/common/InviteModal/InviteModal.styled.ts @@ -6,24 +6,9 @@ export const inviteModal = css` background-color: ${Theme.color.peanut300}; `; -export const inviteModalHeader = css` - display: flex; - position: relative; - justify-content: space-between; - align-items: center; -`; - export const inviteModalTitle = css` - position: absolute; - left: 50%; - font-size: 1.6rem; text-align: center; - transform: translateX(-50%); -`; - -export const inviteModalIconButton = css` - margin-left: auto; `; export const inviteModalUl = css` @@ -40,7 +25,7 @@ export const inviteModalLi = css` padding: 0.8rem; border-radius: ${Theme.borderRadius.radius10}; - background-color: #fff; + background-color: #ffff; `; export const inviteModalLinkButton = css` diff --git a/frontend/src/components/common/InviteModal/InviteModal.tsx b/frontend/src/components/common/InviteModal/InviteModal.tsx index 6b12021d..9117e6c4 100644 --- a/frontend/src/components/common/InviteModal/InviteModal.tsx +++ b/frontend/src/components/common/InviteModal/InviteModal.tsx @@ -2,8 +2,6 @@ import { useParams } from 'react-router-dom'; import { inviteModalLi, - inviteModalHeader, - inviteModalIconButton, inviteModalTitle, inviteModalUl, inviteModalLinkButton, @@ -35,9 +33,9 @@ const InviteModal = ({ isOpen, onClose }: InviteModalProps) => { return ( - + 초대하기 - +
      diff --git a/frontend/src/components/common/Modal/Modal.stories.tsx b/frontend/src/components/common/Modal/Modal.stories.tsx index 3ee19159..a6ce9892 100644 --- a/frontend/src/components/common/Modal/Modal.stories.tsx +++ b/frontend/src/components/common/Modal/Modal.stories.tsx @@ -85,7 +85,7 @@ export const 이미지_버튼이_있는_모달: Story = { render: (args) => ( - + @@ -110,7 +110,7 @@ export const 텍스트_버튼이_있는_모달: Story = { render: (args) => ( - + 제목 @@ -138,7 +138,7 @@ export const 이미지_버튼과_텍스트_버튼이_있는_모달: Story = { render: (args) => ( - + 제목 diff --git a/frontend/src/components/common/Modal/Modal.styled.ts b/frontend/src/components/common/Modal/Modal.styled.ts index 3d981583..3d9edc6a 100644 --- a/frontend/src/components/common/Modal/Modal.styled.ts +++ b/frontend/src/components/common/Modal/Modal.styled.ts @@ -61,12 +61,18 @@ export const modalContentWrapper = ({ position }: Pick) export const modalHeaderLayout = css` display: flex; + justify-content: space-between; align-items: center; margin: 0; font-weight: bold; `; +export const modalHeaderEmptyBox = (position: 'center' | 'left') => css` + display: ${position === 'center' ? 'block' : 'none'}; + width: 1.6rem; +`; + interface ModalTitleProps { fontSize?: string; fontWeight?: string; @@ -78,7 +84,6 @@ export const modalTitle = ({ fontSize = 'bold', fontWeight = '2rem' }: ModalTitl `; export const modalIconButton = ({ imgSize = '1.6rem' }: { imgSize?: string }) => css` - margin: 0 0 0 auto; padding: 0; border: none; diff --git a/frontend/src/components/common/Modal/Modal.tsx b/frontend/src/components/common/Modal/Modal.tsx index 6a52805b..1f047da9 100644 --- a/frontend/src/components/common/Modal/Modal.tsx +++ b/frontend/src/components/common/Modal/Modal.tsx @@ -8,6 +8,7 @@ import { modalContentLayout, modalContentWrapper, modalFooter, + modalHeaderEmptyBox, modalHeaderLayout, modalIconButton, modalInputLayout, @@ -53,11 +54,14 @@ const Modal = ({ children, isOpen, onClose, position = 'center', ...restProps }: return ReactDOM.createPortal(modalContent, document.body); }; -interface ModalHeaderProps extends React.PropsWithChildren> {} +interface ModalHeaderProps extends React.PropsWithChildren> { + position: 'center' | 'left'; +} -const ModalHeader = ({ children, ...restProps }: ModalHeaderProps) => { +const ModalHeader = ({ position = 'center', children, ...restProps }: ModalHeaderProps) => { return (
      +
      {children}
      ); From 7ce9c5ad734853ca0268fb40ee2a3a0efec73155 Mon Sep 17 00:00:00 2001 From: useon Date: Thu, 8 Aug 2024 11:31:55 +0900 Subject: [PATCH 0641/1013] =?UTF-8?q?refactor:=20=EC=BB=A8=EB=B2=A4?= =?UTF-8?q?=EC=85=98=EC=97=90=20=EB=A7=9E=EA=B2=8C=20css=20=EB=84=A4?= =?UTF-8?q?=EC=9D=B4=EB=B0=8D=20=EC=88=98=EC=A0=95=20#132?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/common/InviteModal/InviteModal.styled.ts | 2 +- frontend/src/components/common/InviteModal/InviteModal.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/common/InviteModal/InviteModal.styled.ts b/frontend/src/components/common/InviteModal/InviteModal.styled.ts index 06b71122..549a8609 100644 --- a/frontend/src/components/common/InviteModal/InviteModal.styled.ts +++ b/frontend/src/components/common/InviteModal/InviteModal.styled.ts @@ -2,7 +2,7 @@ import { css } from '@emotion/react'; import { Theme } from '@/styles/Theme'; -export const inviteModal = css` +export const inviteModalLayout = css` background-color: ${Theme.color.peanut300}; `; diff --git a/frontend/src/components/common/InviteModal/InviteModal.tsx b/frontend/src/components/common/InviteModal/InviteModal.tsx index 9117e6c4..26a65adf 100644 --- a/frontend/src/components/common/InviteModal/InviteModal.tsx +++ b/frontend/src/components/common/InviteModal/InviteModal.tsx @@ -8,7 +8,7 @@ import { inviteModalLinkButtonInfoWrapper, inviteModalCopyIcon, inviteModalUrlText, - inviteModal, + inviteModalLayout, } from './InviteModal.styled'; import useClipBoard from './useClipBoard'; import Modal from '../Modal/Modal'; @@ -32,7 +32,7 @@ const InviteModal = ({ isOpen, onClose }: InviteModalProps) => { }; return ( - + 초대하기 From 39fd33af213234d938e3f7eee09e0aaaa8d92744 Mon Sep 17 00:00:00 2001 From: useon Date: Thu, 8 Aug 2024 11:33:32 +0900 Subject: [PATCH 0642/1013] =?UTF-8?q?refactor:=20url=EC=9D=84=20=EB=B3=B4?= =?UTF-8?q?=EC=97=AC=EC=A3=BC=EC=A7=80=20=EC=95=8A=EA=B3=A0=20=EC=B4=88?= =?UTF-8?q?=EB=8C=80=20=EB=A7=81=ED=81=AC=20=EB=B3=B5=EC=82=AC=EB=9D=BC?= =?UTF-8?q?=EB=8A=94=20=EB=A9=94=EC=84=B8=EC=A7=80=EB=A5=BC=20=EB=B3=B4?= =?UTF-8?q?=EC=97=AC=EC=A3=BC=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20#13?= =?UTF-8?q?2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/common/InviteModal/InviteModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/common/InviteModal/InviteModal.tsx b/frontend/src/components/common/InviteModal/InviteModal.tsx index 26a65adf..c8ffa250 100644 --- a/frontend/src/components/common/InviteModal/InviteModal.tsx +++ b/frontend/src/components/common/InviteModal/InviteModal.tsx @@ -43,7 +43,7 @@ const InviteModal = ({ isOpen, onClose }: InviteModalProps) => {
    • From 50b161b26590b3076a96e34d0c12c44fe600eafe Mon Sep 17 00:00:00 2001 From: useon Date: Thu, 8 Aug 2024 13:20:05 +0900 Subject: [PATCH 0643/1013] =?UTF-8?q?design:=20=EC=B4=88=EB=8C=80=20?= =?UTF-8?q?=EB=A7=81=ED=81=AC=20=EB=B3=B5=EC=82=AC=20=EC=8A=A4=ED=83=80?= =?UTF-8?q?=EC=9D=BC=20=EC=88=98=EC=A0=95=20#132?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/common/InviteModal/InviteModal.styled.ts | 4 ++-- frontend/src/components/common/InviteModal/InviteModal.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/common/InviteModal/InviteModal.styled.ts b/frontend/src/components/common/InviteModal/InviteModal.styled.ts index 549a8609..d34abd12 100644 --- a/frontend/src/components/common/InviteModal/InviteModal.styled.ts +++ b/frontend/src/components/common/InviteModal/InviteModal.styled.ts @@ -41,11 +41,11 @@ export const inviteModalLinkButtonInfoWrapper = css` justify-content: space-between; `; -export const inviteModalUrlText = css` +export const inviteModalText = css` overflow: hidden; width: 95%; - font-size: 1.2rem; + font-size: 1.4rem; text-overflow: ellipsis; `; diff --git a/frontend/src/components/common/InviteModal/InviteModal.tsx b/frontend/src/components/common/InviteModal/InviteModal.tsx index c8ffa250..f022822d 100644 --- a/frontend/src/components/common/InviteModal/InviteModal.tsx +++ b/frontend/src/components/common/InviteModal/InviteModal.tsx @@ -7,8 +7,8 @@ import { inviteModalLinkButton, inviteModalLinkButtonInfoWrapper, inviteModalCopyIcon, - inviteModalUrlText, inviteModalLayout, + inviteModalText, } from './InviteModal.styled'; import useClipBoard from './useClipBoard'; import Modal from '../Modal/Modal'; @@ -43,7 +43,7 @@ const InviteModal = ({ isOpen, onClose }: InviteModalProps) => {
    • From 4db39c50044bf733cd81682b54af8d86fc7c6492 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 8 Aug 2024 13:30:32 +0900 Subject: [PATCH 0644/1013] =?UTF-8?q?design:=20=EB=A9=94=EC=9D=B8=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=B0=98=EC=9D=91=ED=98=95=20?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EB=B0=8F=20=EC=95=A0=EB=8B=88=EB=A9=94=EC=9D=B4=EC=85=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#147?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/MainPage/MainPage.styled.ts | 32 ++++++++++++++++--- frontend/src/pages/MainPage/MainPage.tsx | 22 +++++++++---- 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/frontend/src/pages/MainPage/MainPage.styled.ts b/frontend/src/pages/MainPage/MainPage.styled.ts index 22849648..1db89c4c 100644 --- a/frontend/src/pages/MainPage/MainPage.styled.ts +++ b/frontend/src/pages/MainPage/MainPage.styled.ts @@ -1,7 +1,13 @@ -import { css } from '@emotion/react'; +import { css, keyframes } from '@emotion/react'; import { Theme } from '@/styles/Theme'; +const bounce = keyframes` + to{ + transform: translateY(-30px); + } +`; + export const mainPageLayout = css` display: flex; flex-direction: column; @@ -9,18 +15,32 @@ export const mainPageLayout = css` align-items: center; gap: 3rem; height: 100%; + padding-top: 10rem; background-color: ${Theme.color.peanut200}; `; export const logoWrapper = css` - width: 16rem; - height: 16rem; + width: 24rem; + height: 24rem; +`; + +export const logoIcon = css` + width: 100%; + height: 100%; + + animation: ${bounce} 0.6s 0.5s cubic-bezier(0, 0, 0.18, 0.99) infinite alternate; +`; - background-color: white; +export const titleContainer = css` + display: flex; + flex-direction: column; + align-items: center; + gap: 2rem; `; export const title = css` + font-weight: bold; font-size: 4.8rem; `; @@ -28,3 +48,7 @@ export const intro = css` color: ${Theme.color.gray400}; font-size: 1.6rem; `; + +export const buttonText = css` + ${Theme.typography.headline1} +`; diff --git a/frontend/src/pages/MainPage/MainPage.tsx b/frontend/src/pages/MainPage/MainPage.tsx index fb9de91b..ce0230b4 100644 --- a/frontend/src/pages/MainPage/MainPage.tsx +++ b/frontend/src/pages/MainPage/MainPage.tsx @@ -1,7 +1,15 @@ -import { mainPageLayout, logoWrapper, title, intro } from './MainPage.styled'; +import { + mainPageLayout, + logoWrapper, + title, + intro, + logoIcon, + titleContainer, + buttonText, +} from './MainPage.styled'; import { useCreateRoom } from './useCreateRoom'; -import logoIcon from '@/assets/images/logoIcon.png'; +import Ddangkong from '@/assets/images/ddangkong.png'; import Button from '@/components/common/Button/Button'; const MainPage = () => { @@ -10,11 +18,13 @@ const MainPage = () => { return (
      - 로고 아이콘 + 로고 아이콘
      -

      땅콩

      -

      어색한 분위기를 주도해봐요

      - +
      +

      땅콩

      +

      어색한 분위기를 주도해봐요

      +
      +
      ); }; From 2ac612c5c35c1c15f3fe370bd4e8ca7b37d90fed Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 8 Aug 2024 13:31:08 +0900 Subject: [PATCH 0645/1013] =?UTF-8?q?design:=20ddangkongTimer=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EC=B6=94=EA=B0=80=20#147?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/assets/images/ddangkongTimer.png | Bin 0 -> 106038 bytes frontend/src/components/Timer/Timer.tsx | 8 ++++++-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 frontend/src/assets/images/ddangkongTimer.png diff --git a/frontend/src/assets/images/ddangkongTimer.png b/frontend/src/assets/images/ddangkongTimer.png new file mode 100644 index 0000000000000000000000000000000000000000..9f035227e1a06e2b294b0a76862c7248ada19960 GIT binary patch literal 106038 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

      eqvcJ!wvS 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 N;OXk;vd$@?2>>!Vq!|DJ literal 0 HcmV?d00001 diff --git a/frontend/src/components/Timer/Timer.tsx b/frontend/src/components/Timer/Timer.tsx index be15bd8a..54565ace 100644 --- a/frontend/src/components/Timer/Timer.tsx +++ b/frontend/src/components/Timer/Timer.tsx @@ -9,7 +9,7 @@ import { } from './Timer.styled'; import formatLeftRoundTime from './Timer.util'; -import Ddangkong from '@/assets/images/ddangkong.png'; +import DdangkongTimer from '@/assets/images/ddangkongTimer.png'; const Timer = () => { const { barWidthPercent, leftRoundTime, isAlmostFinished } = useRoundTimer(); @@ -18,7 +18,11 @@ const Timer = () => {

      - 타이머 + 타이머 {formatLeftRoundTime(leftRoundTime)}
      From a7f0bebff4ed9c770a541f1bd3aaca8e787bfb96 Mon Sep 17 00:00:00 2001 From: useon Date: Thu, 8 Aug 2024 13:38:33 +0900 Subject: [PATCH 0646/1013] =?UTF-8?q?refactor:=20mutateAsync=EB=A5=BC=20mu?= =?UTF-8?q?tate=EB=A1=9C=20=EB=B3=80=EA=B2=BD=ED=95=98=EA=B3=A0=20?= =?UTF-8?q?=EB=B0=94=EB=A1=9C=20=ED=98=B8=EC=B6=9C=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95=20#106?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/NextRoundButton/NextRoundButton.tsx | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx index a25adff2..7e625816 100644 --- a/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx +++ b/frontend/src/components/common/NextRoundButton/NextRoundButton.tsx @@ -11,31 +11,27 @@ import { memberInfoState } from '@/recoil/atom'; import { Theme } from '@/styles/Theme'; const NextRoundButton = () => { - const goToNextRound = async () => { - await moveNextRound(); - }; - const { roomId } = useParams(); const { balanceContent } = useBalanceContentQuery(); - const { mutateAsync: moveNextRound } = useMoveNextRoundMutation(Number(roomId)); + const { mutate: moveNextRound } = useMoveNextRoundMutation(Number(roomId)); + const { mutate: resetRoom } = useResetRoomMutation(Number(roomId)); const memberInfo = useRecoilValue(memberInfoState); const isLastRound = balanceContent?.currentRound === balanceContent?.totalRound; - const { mutate: resetRoom } = useResetRoomMutation(Number(roomId)); return (
      {memberInfo.isMaster ? (
      ); }; From f1e4d1d539fcaf57fdc23a8291de57f8b27a8119 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 8 Aug 2024 22:13:53 +0900 Subject: [PATCH 0677/1013] =?UTF-8?q?fix:=20Button=20disabled=20=EB=88=84?= =?UTF-8?q?=EB=9D=BD=20=EC=88=98=EC=A0=95=20#167?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/common/Button/Button.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/components/common/Button/Button.tsx b/frontend/src/components/common/Button/Button.tsx index 93b80e1f..a8309f6b 100644 --- a/frontend/src/components/common/Button/Button.tsx +++ b/frontend/src/components/common/Button/Button.tsx @@ -26,6 +26,7 @@ const Button: React.FC = ({ return ( +
    + + ) : ( +
    + + 아무도 투표하지 않으셨네요 :{`)`}
    - -
    - -
    + )} ); }; From 08826142b603284cf58a9c2354a15d1ca45552f2 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Wed, 14 Aug 2024 19:10:31 +0900 Subject: [PATCH 0686/1013] =?UTF-8?q?refactor:=20=ED=99=94=EB=82=9C=20?= =?UTF-8?q?=EB=95=85=EC=BD=A9=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20320=20=EB=84=88=EB=B9=84=20=EA=B8=B0?= =?UTF-8?q?=EC=A4=80=EC=9C=BC=EB=A1=9C=20=ED=8F=B0=ED=8A=B8=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20#155?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/assets/images/angryDdangkong.png | Bin 0 -> 116338 bytes .../TabContentContainer.styled.ts | 10 ++++++++-- .../TabContentContainer.tsx | 5 +++-- 3 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 frontend/src/assets/images/angryDdangkong.png diff --git a/frontend/src/assets/images/angryDdangkong.png b/frontend/src/assets/images/angryDdangkong.png new file mode 100644 index 0000000000000000000000000000000000000000..728ce976187714af3b57c28fb13d789a05f04760 GIT binary patch literal 116338 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

    94-Rfxjt(R`8a@Gy=c~sptZv)!H63H^3 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�VQvos}x9PM`F-pLO4c8f%RW z>%XgwA}fF!l4Xc71Cvss?Gs%JzIF4)S=svXfX@Z`v!S!dfglFrxfAd;l3?&SJr|Ue z3e7pDm*!}*1z%wRiDk++Ohte2zDKR(tE=j_cZ!u(Y4k3`u7s~Scd57 zj{n1gf3(-Wn*0x)ZdRSz&AZp$-0>@-9RB^j5A|eM2g+mj5#*ShXTSWrzf`we3b{CO zQkcQT`e z#uG9SMvOlq5YSPiH-T;IbObiFIj2&X|HtW{=x^V;s6|Cz4gp-yq@k%Q;`twQUL%6&ZHbQn>(=}CGuzZIqS>MqucZr1@DylOYWz$D35oC3 zVL-ra%jSwoYFgz*mnpX={?u)|qJODX@Hz6=W>T*PwA8mUHXir0&_y55;76DOjWJ|Y z0eGg~U^Z1bKzVlaa&X%HH1yJSUb?V@`&|*9q&IsJ(lO>xe8)YenDX}Ur9H)=dmqZh zLf|&ef+T(2c+`{Rvy2b`iT?rW9MnBV5?=A!tx6Xw2KQf&ua>n>d^0=rySWp-Ywc}E zvpx5}4hu?R!M^}g%pn>pnw8(MFXMYa0V$A9KlWf%20Ci7@iDc0ulnM6WZl78n7M*C|<1IZA|K~asdyt=l;d$7My ztmdcs-yWd11R?{Wg$ZJh6$u{tI!xd1DYoPCh!&NtpcelwT-$uoJ@rS)MS{NJ zC`0wDPk8+UUtmu{`!O+pE3UxH99@z7E;?pGCfVrTSl@M3<>)KshYEy@WwO8m*jzK~ z;#xvA1H-{?GSbs05~{*P>$>Zy;I2uBs0I&>Y>-|(%;k{`0PmQX_5Y^@po$#BR!N3283#gq67xv=f8_;>vQG+g<6K52i?eb zIx{N_9z0s1&+&+VEmQ&%1F#?zBsN#c8@>7H}8CFz)%!QV2Qj!19{G}n?=e&6y-AH>X z&93Td2k$})RWz9CNFdH|`)S{x$sY(5h<}@2bIPq{s4}p`NS~Xq>@3dyIT*|BBT))4 z3n`BB`0p|V+hAgtloLWW^W?n=XHDla`8E`qfxga;Hy1H~opYx#Acjv5VR#Ue7z2}Osmqv9I{CEfkm(fZ7#%S?OFk_N@ z`;jVx{e+idbCYL>70f zJ|Q%;M)2^W6ROPlN2f2|=BkRjM#zUL6fnjhI+?fN*jb8PPRNN_)BLi;;e;9MgF9_= z1;yA6f(EF6H!ulYI_&Hwi)JukOB^l`g!(Nn8?lQm8=X~M+lcpgCg=ImA5Jvb6)?&` z;E`y%fy@{YX%Lo*zAbx6gy}?e@nXnP6r}me20CIEuuEa7Q~G;+hy5-8ojh6j0FRYJ z13wdQlB%0 zWYxfriLvtirX}(nn6%o-EEE3;g{H{DI<~i@>JOq)#rx+2AYiak0z`V~aH2V&c3tkR zb@v#EjJAzC$DOr4Kr1z75(%ut{T`t}he?PB&I`?NP-$iw%;KnywKX2ewdq>)uI5MZ z;1B+t2)a0y5)^nNLOuIZLJ;*7rp3Pp5e!C!B>Uw#<_hCo+Ch=X+O^psR`HobbyW5@ z-6{aCZ%}k09RN!v*mxTV2^fSN)GId1Puce?;E;3f9OT}CW}-7->pUZ2Vqzkxg_BSs zjfeVcmXY${m_VYpi%B?bR=tn>Vfjsv>oQHu<5Kae+iS!0dw@t>-ys*ay36I0~x&4xDKqzQ(~UDPj*G5~3}|7;}=21;Y-od#Pr?~Gl? z$BfSc0s=1DHTq9CM>6>KaDiN}(G8urCppXn*chNs@VdFX<7RKwadnaYHo@7?|CY{V z_#;O!0}1(JAU~FCqzC%H2PeRIZi8mFN=Bm8e8s;cW|Y2Huyb(Oz9oD8={(>Zhhg<{ zBZSBXEPxe|>c8cFy73_xk15;k=l2CorK!@=BovnuQNU}$@%|T)1tLV4uv2dqebq1F z$)Q)*BrQ>D)Dn6;>qpl79oT^ zDEMt0$(K}w<4`n;c$rskpymipEu>aaSLb5ptJHW8O?QB;NG2M^$wl%;YkV2?%e^?> z-@Cb#I+s|Lmx@teRt(Po>G6X9c6hTFT*gO9F&;woRf=r6JO~g(0s*)l91Hp|u zeYLH?uN1jy5HZq&0hA){h^s(qh_`O)TbYeHxlqOkAlbV!Ion}p*GNgs_V+@jp@f{7 zVW3m{^YwUnX@>5QD!e>OCNu6juH#kxASon1mlFXPNmQUpsEeTF4rRMg)fsu?#+10E z#9_oFlGM=)H(r`9sD7rVfZ{ z7!Ckt@z)Kmoym1E#jtX)N$E;Wyah+)v~syJ4DX50&kh{gSpA#0j;DYDDblyEOAOvA zrE~cdyH!;-##U7w%cbPVXuoEGq=C&CLI9P^3PWAskK8yma@=GdC1qsvo0NBM@yUcF zdUu1ZF#kn0Ffe0Pyiu-P))V~oF&8dc-09^yw!~gBCPD>f(*qwY5wM8`BQ0(`I?tl*?%|Ffx4Yz&^CeS$2%NUH zDO~D#945n7ZJOub;=Sed4;Y2Skb!|3(qQ`ZNvd@TWH~=8runr`0p9ly3U6>{tfeQ8 zV=#F66~gcs#D%eDKTSH)CpDoMG_&EIrE-4)J#Z zBG@3CAbn8VA^7bKi8OcfN2Zo4XL}AwMsI8+&kpZ)QL3-6(z2qbjXZy=(`a%oK5{euf|#HW3XQYYenZ|qn^9W*Hphh=C( zCKn5<`u7UNV4B%m;sW5B+-Yf7KQW3ZdBjyu{*%(tzgmH14N2zlzTV($0A|1KC-Z^)%nS zMU;RPLV`jR2NpZX4Q5sb?Vkt>D%+hzNKk^ROJB(7efrKa>j%P1+9{|ptSHL`^W z=il@wL?8}j4>RufA!#$iro>_;j;ui6>%svZmk66BAiGhW#DJ9#reFkMzru(^@bo!V zt=U4{pSCsud8wz*VcjUj?c9^&X*{7{4VHv(`cz0_uuuNG>14s?0<>S3pfvR36?aB1 ziefW+cLeFXnAd^ym$(Xipc_4aD%Sj=C!cE(X6I+MyoJ_DR2ldlX*~l7;o?N;^bAIgv!YIr$ravOt=EF8pG-N&pYZ|6O1;jhMA!VjZEtX%w(48Ct*+)ysIN z@b+K?1O=m{Xy=X1J4Z@Amv^B?#@!IM!uZs$j}AD02BG|CgQ!rD*PyRcI^51+*Gkzn zNM7oW!=Jx7Q;H;YNCv?av%c*Eei&odVs#v7K3LfeW-4mRPN z$PrAraB=lskkj>`u7chBi}@&o5eTxS*Cg(i(9+fTt-%FV93DO62yC9yEi`@k3~*44 zuc5S@8#NIoG8BMwREIltY~RFaH{r1;@5GcP?~dU8A{?Zg2c;uA#r$8dOTi8U$zcf0 z?xs&H=XUYx3m$zV@CG8lmd&e^8YcL^jUFZ2J6;tF^mnACCYhKpk8xc z`262HfQlj){#){1q3jMz!IbV2L0~0iRD(y8USGH;RI?a``>W4b>yjF!!QykX?AXKFG5M7!oO`pyMU;BrUXpe zcT|hK%y+2{es#&}$}+UIwxv<%K^DTOOSH-drM1M^gP6B7w&TRIL@a`$p z;KR-7Te!KT7YlJ{cmNzZvop28Ly5sW?-@Ps5tT_(D~Cs+XWxF|V@>4b;*v#=xQfx4 zAqXKY`D+Kac&dr9A;***6{LFcap^nbF2N7CSfNewD;3(F;|-)Sz~;|FTU97M zN57-k`FEP?h;C2fx7Lvm33db;b^xRzuJWs}a3Ht=*kyEnKzD}EkHk`Gd}JV9dMSVs z{ong^93jH4400mZ<^ZL9I{a89MJN)bpzaf#(*H6H+*D8w&3ZOiBzYn1M1$cqL0l#8 z`S^u!v!w%J|MQfR3gG`k)py5J{l5QmI^~cpWp`{Dkxk?jo$S5Ih-}$=bj&2jmTWq9 zWK%|wEwXoHXC*rnzW0gVzt8XS@Mpcw>%L#tzMj|fn%`7Iw`-K4hhM4Rr`DX>6hwZ# z%kgRmt3htR?jGurnqbsc8PG4kwAKrmDOXb%Auq#>{;8lmgy{joA{UKJkej;kMujVC zGH$0uL#6v?T>u5CECmpy!E8)_cL#oHKZjqfdUgZ#LwO_>QF$(MT7=_Yw#|n7h`aNvbcE!J#+w#t(UAhRf=#!NWc~c%0dY=<}<&iNd@f@)rE(~ z%EP6aE!d{g*&h?h`?4Wv&~z`TFDez`d7n^XNX&Gi9PI~4|2V}4;1{8>&%gs0R=BKa z@E`#Bn*O?bP*+66vM-7hrDbA2+J|6Z#=8r42zw=Wo(kV@E|`jvItyWVwf;kk9e z1wtO&fEW;CiSjFZaw_3(+RZ5*rXyWOD(Wkvn>AX!ewte)^CK(HFA2dG(5=YsL$er~ zcZt2o*1`TdkA`svB)}XFTs*ZmzIYoN0nikJpr3y1!qnYThLQJa)-V-pD-Ke-brw+D zkeR5Mg*GE|Se?;rCbA4Ac#}_{7n;2ENuy65i}K`W#aK(D8X|74pobx$4rTTAEsDVx zQq;sB!Oj91Sz`$Cv=4L2s8DT0Bg0`3x20-G|EmuljjSh~L9cmo&+0%H289F^#Yl+6 zT1M=VHuUG$PhLu(ycRRa_+^2_in$-J_g~F&m8{R}`U1{-{vVo}R%|J8Q^<_o6dnV% zg#g5BtS4BOgdWeyH_mU#(o(f}!^*ZwMZ*Qc=t7&UjONdZzgPnz26dfMai_IzZ4GgT zhRSYvHf&>}@2xhn!dPg43OpZS?qkn_9r%7wOd`O4fH}Cq32+<9)T;lJ@Uh_Gx?~_} zRr)469PH}U46`jBV!nOv^#nsqyz<01`^cdSK*>3tF=uCU;Ep3PAqAy;gPVfer0q2= zB>x)FIG|YjYEoxKBHP9r#m{f2ncX$GytObgIvN#js1pwjSYU=<)tm*IOBIM3{hm;r ztEOq1^sF`HVrbs2MuFG5gQ8I1ub0kjVn7(|;KtxvHB*0onVeqDu#dFnA|fJ*87pG- zB#;6bob)!$Ri(=NoB>#rEkVYpB^7!k_d_`+2S@kX!@)2X(ehWIB71hxVb68Zqk`h& zJnGSTY@G$8YduyrHibC$q_XUgO~G6Z2TZXk*-T%YGna&rr^dI^;9!Zb->tbj*q_nc z(nxQD6zD80c+CWF(~FT58r;aNHxvRUlY=6nEx#5&BrY0s&g90dRmFs%pl{770}HR8 z=%$RgXQUReXdTZ^ANwz^n8K$@>Y@$|YS!4<2I~1b^5x5`ps9SE$kQ`Hg1OZrPS-;( z7O=m+UyhP85yN|6&JoW6^^`P= zw0p>1!8e-FLrd~PjP|2i2&kDg6rb$p#3wPq-y8QxA!1oV%Rz}u^b4?|8+!Reo%W0D$hb?zlBqo0Z zY*eJs&0;qg-#a2m(;B6@{d-12r0H{Uxp_lK$9{Yo%x|+=_z8ol{CI$_5X71rB5`V^hzLY!KUGq2lfrYiL*i!^gpNxSm!0k$ zRJ^cx`rqKzb4eRM-TATW1`DnCIA>F~O-~py}m%>|9a7bVS*Y3e4`4R`$#z0g+ zEUb9=H0|ix25rsO_47ADA>yGjpTu;uLu0MSQ4HWKaQwz=jeCJLzhLh>tuzFf@|)?q zl{>1KojdA}idm{B!%XvDbDqU1yYR-`*L*Y;0>i<1M}8+CSh-hluM{hKU|q_w2+oh| zu_&pT#5*rIa&JErQ)YH4OfYOWe3oU-2$RI^Y3p>P z`;!qU{oRj7l7W62dC`uM{}#UNse0barcZgBid zZJAl%ZTfXeNAeUH_vr=c`Cu=b;HXkRPeSM;IYejToUSmATL6k5k~*XrV)rcW*{y5^ zt$?flf@2dLTw3;KH7Cb%iMr7>&_uat*r6y3vAH9MKd#Af5i(1rnxH({l#Ucyvhw`V zJb3Owqs5^`b_>Tmts#9c@ftO z3b5MG55eyz&1Mr%XRGB(com1T{QGR~kWZfLX|E`e7$y}AAC2FW>k)0{r)~i!%xoYC zY{}m=5hvrjT7xHc;rAstKIwY>;-&xWIc^eEnM8$>qSC#LMW%@{0(o-Rvk+2En)C`f z;wt_G{;V7hno` z6g%=$V*v4`o2H|qW0T`=T7$v{WhQxuoCAt?KR^5)+0lowBAMCP=D&SBPh;T2u+$H^ zw;GX{M0Oi3xUlsG!=p|@#>^anObasp*Jr{W z-tj0I$zV4=m~U4<{KNfr1X6DbPYhoL_^#leOdM1XAo3AN%ATD$JyeI@CJn8+>1P|G-xsX<#b2w6FjtQ?@xJ$a1?2?&?xg;|&;;Vma+T;RnjS_f+ry ztXnVqNIOvM6unv%N%}8n?38Vcm|MAS&?-}0NH5aj5ezWCmVW%sfnVUH_#hUEQI$^G zh4)Eq$l5#9wD$y2G3jUD3*kGnQO9j;lX5kXEeLXd@KVn3Hv zJEHi2qI7ay{_4A5u63Q)9|>+pu!`u$B+xvK|1bG`bPwT4i@ud$>}SX4?zYEKkhrEA zXZqlIH7Nn4AJ{7@NoiSteh{uxdfq=aOkskFVb=6vm%ezXY$NbgMJ?9qpL=ZyMZF55 zG%KW1JN8ejtp(n?ekwHfC#)}!C9)=~2A@S`)|eg;MKM! zpqgiwX|3D3R@$0B=@o@co0z;EU(hyNARCN{xCv!v!iLFXTzxkfVPLg7-LT!r1nfO$ zn)q%*W(6(F^E*S)({a`~kj~XB`pQ zFlNqCJWa6Bbx4h}9JF7^6ToMY`9Zx*=>b`{wsRf(T{9J(6*oXTXhZC~=sdkUNk#6t5c5ELEX}=O@(GnK z&pRR}iQ(RKB+*vEt#vici+@9&=n1H&rqKRWX7nmV=QvCD!q^Byo=gM}$Z%-Peogy6V8R0n)*MtUb4s6ebOY33PKEEqp;nFVVCk*qT}KQ zv*rCCnhEd@Sz^>qJagqAcl@&jP*(Uo4L4>Vo2d2&Zb~-yH15w=@Rtu|KUPvLSG^2{ z0wp+*1lSvx;wwJWI)UaJVm$>NYe>z}F`ISfi*KA>5jPtAd!I|V!n9(7LI`%+WFG~+ zap)&f{;wE`egjQISG#u)HW^^qSe+^udt((R2mzD>!@!jdSYBx*)t(%C6q>h{Y^$2p!iEz*3 z1rJ)8{AG0rgZ)|ic(P`*FDNfUbAPysh=E~D5#t0coFO}ZC7b|8{LOGA@npZ9#nOHM*!n^+J^{Ntaue?>|fSN6$jePc^q$v&-I zT#Kb$BbOT*gpvU|!ulyVe+ZZ{LtkC@&k%{)=eQeV&&8d8z55*@JHCftIM>*0JkW_9 z>wFJU9vb4bbw(mDebPwi51IMTyRbq7ZfJa&h)qkIV%4BFL&jfZxa}0%tkJM;E#q0J z_#yh-X!t`R$#LR75Z6?UrzV|yU7D!Ns`8l`OT(J6pNz`@E~t^KSYUxsvk5B%RXC^m z-1M(cJZY3@4z8b@R3_#|FAcH4cDaYC(7dH=8jPAE9Bid}@?23m9ulyCb$Rc9lT5Uu z8o?xTY5$_LoDdC9`&@rq3zFGVwdzSrreyvZDh3Ctjz$4^!HA%H?Qt!qikY^%_UDCy zxL>(6w=3~LM-&G+FUv8TRLLHllrYXl5lHnlIE_QSbhxH6Zjv{fSw>5>@n7~aOHMke zb0~=C_O3y5l z7tjh~;At9f75d?nPyzrDjjlW`-8WeONHLvs3$-Q7b_eyF_&Vk-!}>54!(EAgNplla zaCLoupvi2+(cXfD^z^}P3xg_i%g!DLlg?Hy7|R8qJDq(BeYZBCV4y&FJM@EO`ITFj z_?VFi`A2>D#CfI|vUH@LCnMgO!|#DDC!;57B`Z(E9t(C|G^rT3>V9?0XF)zhkW`id zd)~Z~OlvxP$Lh+on>y|lc9bo6j;Cb2ZZ6d#gFiXyE_M8iJ%-rfOrEu%WH{63#EM=F z_LNMpWOOMce@B}9UyH+&;$W8K={pH7E}zC)q@MWjRwOMEx_IFi?YN`)^ANg!H^&SS zw)yEgI6J+mskcVOgQBw^5_anvvRR`kfk!{VMpgzF&Jt__Zr*P$XsL_8+$C1`?57yJcH1h0)1Nt_}S#(y8BWh3~rfF8OD}wImH522Uj^ zaL~b$-u^il{=(v-+&3Ows)$dHU!NX`?(LR-Ci~CzA*i5&(;5ApYt+ZCn=>(dT_L}$ ztgh~D%FkPq%KBq(>mx~jAQjn+8=5v%IWH-ar%U|)Si}MTF59J&JD%}1Q_HgfCBKmI z+iL#;jDY~uqP3kRW~)z4XpQ<}`|H z0HST%A{y{7R%C%86Wy=2v)lvF3)Uf->@g5pY;0lZWge^Pr>ht2BQ$M z*rYF;9ur^7+v0HG%D*$>al(&zsAEmut>&Kv@I_!pYmVC7JzE|E#SU) zu#EGw*J=qKvl%qzB?fLS`ben9_Yr3;gfrfPE`AGFm zk{{zzuIb5E?Q5R`KT%jC$d#b~gM|%%T4YH22>H;iwNCYICIqMuKNZp)H+v|v$78=h z5~d{j|1xhvB^1TX=3FFdDRV!PVM43n+aZb;%h#mpjJ{>&C zPz_R9EJky%e6oL87XQ!k1F0hp5vdwvJPCs)Q-bBodBs9sCV%&hJDDDCZqGW9VK%P5 zYBXnh{vOnPH80jQQHcoM-t%-7_b(6l^Wg+v$CL%hk2Gk@+2dTDH@rjy*j|w2sU`=a zD*yeG73|6aC6y^>46%IBFi)s>v(?wS4DoR*I#0Na8=S=OtihjsE#Sny@Cbbu{imAH zW@UHaZNqQnW-_~jw0#RI5kMclDu(~1mM?rpjZ{_+973bqpr0cF3cz;N*1|>}9jE3* z@*{tiBPH7_-`@0)5y_^Uu_oR0NPDRB1Dm9XUAG&Oc?6>-*^D35f0^6!KiTm zpjtRyb`YZ@P6msW+4~g&q5rGN6rQ{N4-$b*7?v-2`OEf-#aynv&mQp?DEodo`7`S9 z3l|1Z0jKAg3xd?7#;isM!_1ztq8a5REq;w*EyeTofy2N>X*iHFV4D9{pHHC9JI)Cq zZ|uIlSGhgRx^F8;bYI}ggCfuWW@_PZ*fQ2_6sHLPC>;^#qGkuFdexIybX%O%K@-Ux zs1vZ1b1HP81{6?=ACKnLAivCfCwi@>YKw+QBx81-+PyvVELunCllIvOix014@!bAh zGZEeIcuUQ;IHkL{H}Sd_i?mz^PJk$BW6gjl;z2^Eipg}Umx3sf$D8$+VO|4lCqElw zXr_M5l4=#%#-pjW&khd?SQQ%E z-{FYmH+)v{`E~u)S^`CqcqWm=t*=hg7r*n+J5pSON4H@;fYW!(NL}jRoRsEr2B@NHkS&aLL{4dE+;eyp$M)Z0^dS2HXI5#jLSW?FK^RoRia(; z211K}FKa%l^Z1DLq}6f^Rs8GuK!>dFr!}FYyGG4MW^$Xmxc+Eo*XImPH&J>pd{QM$ z-GO*O8b%4^sEi5itsdD3FgY(NuU=u$>F3*OGHfu-n;z;)QQ6xV&410%@ek5t&IEt$ zkUaUd(%;stWWt$ED~S0SK-T(Dh;hD9xhUpsE3s!qsH!s0EMT4@Br^b*6`66x^qgZ#S5o+i=bX&E#RlB|q?7o)iSFP8uyzjv0*Q%l*% zX&bZQOD>X_KDGViw%FKMX+Uavy4_+URf!wWg3Z5g9pUP;hy`4{e6@bV`Mr2x3Rw?f zzLszwmt*THdT3~%OQ2XnRzJa!3avY6O8siYzW(1e6_S$TJNoLgRk>c;EuQpHYh?FI zd;?cqTwJURy6FU>8B!T={iKAcfrxA<7`jhtZDno63;g`~6>e2T+c0gU#$bVP`6Qj+ zG?MB?Q>7E}S@9$s+FevIKGZjt8>LgMGtv?m7&!9gZS87r7bgl}Q2*0`IntRP6iMfR z1*)l&xb>=XdaY?YuFb~ob~^fkR5eT`;Xb|dnedWFp<;xzq(;8VtyR-&<}!R|6Fusa zCTVz61c6-&U}5LmoV1J;xwIODkig%xXnfk!)x{rIE2rMV2NQcy2$OkO=Kkg;`J5Fa zl35}$)p69re|E8we#!ZR7K3DBk^goynJOSUaO;Z^~(I<+ltiaA=Tz6N` zY-f9Cf)_Bf>m+F5G{K|)!$d!q&V2Xopp@I5J4h}21DP%D;>Hd^kRUg@c z^Y<$n&tf&iHd$W;w*#FX^FZJZ<4w073TlrF-1!49G1N!yN;QTH&Vy`p7 zE@Nrrx^>X!C9yUoAD;Ng^T)X6=n_U~P575VEI~Zyb*&FN0lHz(fOsY#cR95b=;tB< ziGU+oZ~A+IelSt`ZVt1$we~*nWU8kxBiSC=$?Oc}D?dXzUaQ=gykmI7!ZQM3?JF9Q*jC0E^ z%{=lfnmz`Vgg^G19!}Vo1|aq}6B;@dhXGF1!_6RxTsH z??N8b81?kee2u2Lnvg+WOrpxm;_*+k3?5~PYDKR91$dn*h@ywZR5+^8 zzupQ5+uf@fBQ-)gtJ=HdRhx$-;aIk`Hv6h_Gr#{e?K7-Ro~sNB+T=;t8qEg%^2;IU zot>oKdR28pXLWyO83boPV>)W8^f9lSYq(;eZZAiM0Lz&PZ3#!|nq;{wL>PPY^-o+q zS~hdrPZemEb6M*464ADomV`$WU_IeI-q%F_zLHahMie?@o~p4 zDyx|LS{JR)1Cp?dxM>X$Mkz0B433W;aE)*jJFmYgoAf{Z{Y~m^B{>W);0kuYs8#$* zj~qATJJ_d1tEZ>;2>PFaV!F4CB^i?FO=0=Rgr?_;%?y8JRiFGKQpjzv z?s~qGl{lc)urITvwt)l;VV#K35m~XUDg!FX2 zoP!l-loMwp;H6#v(;wwuDHCGX0S(Z^R=^T`uGuTVAT_>6FTZEMmGmI7oY#gvxhL zOByQfUBh=0RAz${-xq@tjvt(12XUZ)s4P-xDL#*HQ_x7;sq$^YwCAarhT+c{q4=6j zMK^*Vr_%C}kdVB$?~jrbzi2Z2{A=n!`EbS%Sh{SASE5dH`g-^9h{Kj<>KZ~T-6jhQ z8tM$Rg`zK>zCVA>8X_Ti^Ok<-n+_-jAN>V3}Z|Q49gF{zFRcGv!8Z}pZLlY^xhsJ z8PkOnJ9j$K_Z#)av)1Zg#u(PW+`2-GUQ?#vHM6S>j=XMM2I!+RPD9+#pg$F`38HJl z3~G54q6O+HJ$w4)^Jm)xF{*tovszkXKOgF0LHFHa`}L>SEzd0~DKF&F@goP_2-Sem zZy8qW*&d1ZEG736?A&RUGVYkY|HKKWfer+sIx+$Pi42&>0b4jKQbvWRhrWK5XexAW zgxgF-ENd~xK)zcAJ^LbMNv@@Rg)Ayz%$J$zCC3?#H8T)3_NZAwdD?JGPSq`#H(X)z>J{c(ka)&EV7KPc-Z%fWqK5}fO+4k(2RaJr# z_qX6vs6_cGaqU}i!#Ws2&7b%I7@!1o%O4`?9K5{WgytZo5*(pMw**h^=kX`}Ghf#F z5`TFX6y-$)+v5293qa13M{Mb~y?ttW?)ya63>f_M&(6&Ck73PWt*V)FpL99)aJ&Q} z*&DdNDG~8>T>*$IP&Sq1dbaR6>8q5|<*!;P+dn_mlV@LT{eTX;CxV)hI!iW1$wrjN9gk9`23|>dCbG12qI6e8TQ&@DN{4V?<*0Uw1BX3iLH+Cg(ebl~_ z>zhH7(>?x`)gakwZ5lK5W6On2YcN_<<9haa;N7?hZRuDT5$GshRNsq<+x_CB@Qjyq zvF`Bj@CSC4#$~neyP$*-V1!Ll-rzu-m_URPSnhW9kv;Qw%1oV;ZN}jdp%}EKdki_d zGCkVn%)N^ew0-%_ztq=%MC|?jcyVFN$uQy*eh=0^`u^E!H^%h_CldqysB0E>15PR& zfSokc16^M3^+0A0lOvkv+8gR4!YC_ndA)TL%U{>M?X!FMltXhrUR`v`eLKTjpLfh>tPCTs-G4fsX+ZPX)PRom_sn-9sUeU`W=$231>dKn4^c?G zDXFie<@Ojb8R*5xiAvw7rfH3MV%DQpYd$T=$R+=V6aX$9@QzB{gSBd}m7k-G} zxZ3aVl=&AKHGbRT;Z_=MJd(Qyy#);h>uhu<{UVGL27Y)s|9Exy(ra=KDqzS z=4_DbR>=4MG4gBH;ttJCW_3Ma7uu`a1QyTE+BgBr_+f4l7Hyi>?8m;zkVx$@y`S0^ zwxARJl617KTkCXKzIaO2un&S&tZVvqRr>i14Rj9SI$4Rq!9n22$=ubP$)$Dh76xT- zE$!h)m#Uv4D8JhY3X}PjK4KQC{M~8!dG2DAFagzD*)p*Qr|YHM^zifE%oHr_xvT(} z4T_yba^JA8R$T6s!|gOXw5184aKnBu*P`O{k1)2AXG zcu&N7O1c>xeCWq7NYW{?+|zVAhbACgp{~RVL{`eqwqm;*p)^NJ7gQWMR#uGKre`~J z<;hl93UXE|R|d6zPF4IO$99vj{DqB!92qxQ0X;kYpl~h2b4hHq zi%L53wcNrWKU&Y!MW{A@d@};sKC`f~87O7khXVXAFCq%+qJ~y^Pwt+$KW}0{Hg#{50>Z|Mmn>3J zm0*}Z1N_AEZx8zTdSKiSYj+R2sRei?!TwQKEv0K096UToyd)TYXk0EC5}?n%C{E)U zJ~mpX_3V|<)vD&T{6Z2q$izVR_Bk+Ndp0)<7b9$+db@;F`~GlW?0J){UKROE{DXqm z{d_R1gp!)Ynj!MYMzC|~3(nJqaF)q%J{Wv!fQUX_6^hb(~OnC z5FNVE8`l|oAh-~0xxv8B)z<5%P10>QZ**E`nh!my0a~19N!#J7xPT-EjEFJ&lOf=D z@f9<~j*oRkkNh|L=JoA0@ZN7L$kuFW(_QdfZeVD~6><8fCJj(grVwe3&X;$8M`aB7 z|DJfZu%XmJPovC9K}{RM_04yu=Vxa;z8?7K(je>>6{M}d0C8g7+zOBSc*kpC0bLkh zdTFQFKx8n($WMB$Y%z|fA{vdfwZ{}DGyc691Y8Ri2BWNzd`9Dwy1P}&Q|UjbZC0)p zaZ9@;Jfd3P>}7O9V&bUNJdw!By->prP#~b91_34Wd~hBDeiORXn{iq`xDsvTv21d( zX{ORw7RpfmxS}RT*f=Z;oUhk*!)L~XI7z-{g%O|-&<-qV21rtE``{s-IT9FFi`&81F%W78`8v3eu z?Tb|6b{fO>@2_QH5nAIc9cQjkRTd$W0~KUHw7)4nHj{JB$UjQ>hiHB&Qe(H}Ifd|( z$?6}-ManG5|5~wVPbf&WYK<2c7FE%NLvw|LE~wITgw{!4&rIbwac$BK8?RYQ4VAXiNyIv@SqJ}B>-WF50=z? zNAnm|e=XF1UUr}6csA+2pqnq5^@c{hdTXy%@|t=#kEo_C&f(cjJy%97yx-Ee^gfNX z($s@!>aYGQ+j-q;tcwBKQDU*JKXpv**(qE1s#X(5ot{G$XbzA6&In25jN^35iAvsue5LD{+4L?~;=p|=+Vr-hrW*9F4Oiq*nJF5W> zS)hbiFJx?kJpA4wlFCyxoFb<%vYu&NZ^iZz-@c){Os)eIdn!(kj@C*}4Xh-wGYMft z;E-m`)Kw_N5cDOl@kuWQyYknooE!txQ>tQf`cO>xyyfY!&qUp+sHJ+(4A-lOOIOaP z+Z&aUc(mxl%AL&{-WxT%B=UfcaAb_7*^`@>_qID|DM;~KJ;pZiNwHH^W`WcRC=?w; z$Iz*jx1zjU!a19W^*+X|N4#P4NL^fW($x1Z)vDZAyff&9AH>3(ll{Z2UBMj#VS4-J z>{f@Hv!z2LcWE7{Bj$Q$cJ5xk)2x&-h1~gWe9%<`$cKpjPQBy6I9O1dnjwyiG*EMj z8FNuui!Z5OcOO2S5~QxEkzQdx;aivZDua1pC}`#^_V}@hzcq(8VBx`DpK@b_$n20+ zHTUZFeH6nMTG$c7jcKWz3TQ}U1|nk2~?GFzCp0<95_4?hrLzIsWT^0QNnezFNB{Jub03e zOZLf^H~#A#car_~T{(F>7qdnEiG}90BJX~tLq~Yu9p!fmJRhF)B%hJmNJgJ-RPhNzvxlc1F# zQY}~$p;3?pyDvIDm!p{SELTS<(@;k^uN8kcr;RMs0^Sm)2?jdP5LhjNsJ6HuKzjWB zNodLt^jwAfeqnk?Ehb7c{LNDVb<%YHDIR%{4ezQJ`%G@=myfkgo+8Bf!5q z(*~#$lR&*QN1a+Ar4ae?_%rgzbIN^nw{)%lm7B0F?7i>HDVjWb)1Vr#bp1l!Z3(JTXvzfeK^X+WF>D!V{G^}D)&K;$H(7Oi-oHwP|6PIfXx^fn}1a$fRcwcF7>2{ zbf*jWeCbS%6ENqXT$QS{hzqgX!ZVxS$7l+Hr8o4(Nad7I4kY|E7pTunu_@^c8S3Hl zJ5xs!v}Hy`E-ztOHH(cJj=qpdMmz(y|B*ZZ^uL-z zK89z8Hs%tg+z|i;LP_;(gR%z=p8}<$f}e93CQBU;U$<`Fm|v(~d~}Mu(Z~3=!aApb z@FZif2NCoeino?;DmA+z;{T13LbPlXX<2xm)dokWd)5|bF!qKzC;VU*0 z-lAV-ykaC>b{+HNb0#y-+fO4|`h)h?H)7BNY(-ZXZ zN8K_uet#IY-|g~(NK1>Yp{y-lZ4ndcfB4zhC_djV z^BM@x1VxVRhdTJKr3WG*vC=aY5iui&sk3%kl7c%?e{-=@l7>KxBkwn+v?@=Ox%0e zF#Q{-UDxO+TqSY>M~ekUMT=iG>;mZBj@4W5o&@Lb?a5+S4ImIt{Mq5;Q5fBR|V(pB1DOM95r^LD!wQX{Hf;No^V-_ z#i%@;P54z=BW3uxu*{VD0`EMQPk9~WKy#j@h%|8CSqg-w%|W*+1R5LInC3BcSQ2tS zWI+9!-kM6N&7bx^g-R@Zo@ zT+;AS{`dT;|JWO1pX-#TxE}8fKLB3Mz4o#vQmf$0gr$PqA*MoFj#SnP@;Q-5%J)ar zsKtg<=_zNL^nI=Ck1pB#%DU9mS=}FhLn}Vzv55BP{I}Q66O=D9ncsXm0t&9o?0pBW zJ#G8@fN`QjF8k9HAEQap&C+`G$XcTZrml8(K*9K6C*$;ws;jyx071cD0`JroE4&H; zjOb%vb9lRDulVo4qobn=O&y+Yb+X+`|KDoKe7Rw{%G?;mI_gW0{a5&UwbpR|27u8U z&|nPT(3n|8|2y^w;hAP{*(Gz_J<+ z#M}cwBZdHjJAR*;>qD~*sw_TnUy&-7ux?oH{8m1?1v7SeRk%fTDIGcdhw(2U7X+vh z5ln~ZC%w7!&-9lIzSS4}keU!3npc}5*>ff^C4Lt4_QTPt<#o@QfX8b14@`jte@6R zDB(s1($Uh!SRBMt-^BwL7iwLj`USYqU@_1kI~xn|E= zl4W+;;o{yA7$SZe725^B0zzIfaNI6341`pc5Q0Zc=ZW3XyyN9Juc^R%E1#<~mVKf8 z`PdLcru6SO)+624g0&s@lQ+zQhKr`WDY+Pxq(=q_u-QLW_Q{t|Q#j@K*+1MmX$!Z$ zz0b#BQ#QC$!ksfZePZwqPzc^}wJRtroM=&CeM_JKV*r7#EC=M(v`YR4iXWc&vN4kW z_7esv|3AcUuCiWYzAUmxP!Y2nw|ezx#pQ+d&*$3P;+`ZAPPX|sNz;1+Jiu55_J>J{ za9t(|(@x(V39;{uy~xiM2ttE(?(I6?!jYR{UC9&yOV{1YBDc7JgTBDb8HROYvK!kdwX~Ej&8~E`p44_3XfHi&x5a$lH@WDyDd+C0O0+{ zll%|bL*QLAV*&G5f-55}lsp<+1SXjVDelq9@$Zt$(0d+B>X_04>55|$W-%dNr4;_8 za>H@+!PZe~7c{d3+UA`!CrC?<$YIezHNzcw)d=FBt?$%+clMq<`%`up_YKc)_EQLN z{ZPs^J zb3Zj(hCtM?mMN=5b z?S+#3&ph8A(UI!$s}dy(*)Ba;8!?q?BjtVv{omhrg^ro{+RG2eucf3IaE8VTe!Ui$ z)kWxGTx9Xb{I^`R4U2qX+I;KFYbZqOc(64jh) z>Ld*HW=s8zTMcPgzw5i*O0qIslQ>wQe7!d;6VLUQSEiy zEsude28Fi7&XWYYlm?MDQFjjMhHG5+Bw2UN^W|EmZ&uvw0Nu$jDUip_ zf5QXgd2{k8ig~(O&E-*-N2%Ov3aGt8`CD7V7JIotnuhU832^}0HrUy(seN_$#8VTD zsqNt`fT};swSXDNp&6G7O5p3LUVxi6;~mnmyOSw-a8RMC@r_~7LY$7cc58|Dy4S1- zuLQ+lxEjEIp#CAx;L&4H?PC3^U;Dk&8*ksf{qW`IPDKNUgzqQRn#iw+ z{9-oITpzkMQxa60&$$ z^rrhg0hwlmt~KMIaE24T3U?7S{o(+-5}#xw(;LpSQb#}&{;Q;%9;;{^v4Tmpdutw} z1I+8DMRyEEJQ+hg*mabrt1Wxe6|QLG_5&;9#DI5NjK6d+a$a<5)LcBn|v6(oDd!DxSrKXBDuO35yJ=sM+d)gU|H*H2O)G<1>lT4 z8S4~2HUNrDGnZ`pOsMd8wmi{CyP8D50!Qq>DwL635@WrgRu0`srPrlPlbr<~B-4-F zF%>iBiXVdRe*(*OmgYXL-QnnYb$scEl<(^m+DTEQuBYyvU= z&`)9C_*zBy;9ddfH`R5AJY}T<&DCdi|07x2VQnzN<|4u3Tdmav%Kg; z7Tl2JU>fSUpw&wGi-75htQy4_5VwhoxKB1%_Cr^_<2u+b4(e6&os{!DOHY%`aNbcc ze6WYeADMn}oF9XkJ~&!Cl~@e0i)I0bB?dn~WSWCu!5$WDCEH+l`s?6R(UhKuo^6ql zHP@;*3!#a0n`yZL7e|gIXHs+by4G-)4Mvq=m?-=;65<2&%l-ZgonMTK?%g*PeB0s? zmN^{yRbIT3zvm>xwRM-`UK@L_bv%H18h5{^$|(Hiq3+E=Mce1t2yNBJ5V z)&n4ZL5GBuccM9WKJ)iajAyHICOlePTnqVh5UQzbI2#wcIY4td1(L<$JDqe%z>pn8 z;KU;{vL3X-XRbp5#}c+(DHMZ8%t(OHEBK04K<&qn``}3nWCFi@bmo(>1$`_OcDZ=-p z0q4&LkDt@D2O_gJDoX*C;C*-HaO5#})-I|Cpx(mFEiF$S$8!>M7M7NXcT-JlEakFG z+yYxB-8RJ4_G2D(O@B-r@ZQV5>0}z-s%H4+qx9F1zXPy;5>QK$TJ(3b2=iyIDsxMk z3%pv9(Rx?EP)8(ayD_QmRYlW2$@(MatJ!G4`h}o|G~R6xm-pe}a-fg$@nmr!wd{=q z^NB&8pL=^%epQ!#n)9sO}KITvP%+lm?iJrp!JIpcUyH`NILbi_ye{Nq-AE(--|#-~_kGXLn#E$V*36l6?%n&^ z`%2K|kPD*^yNyqGR9~K{f336dguO@y>t5u(PMe_Din2F}$A2^DmF^3MqMcpeEX#+A z+)ZhGn%q^g$vu=3M&|b%=?HN*25{MWk%hA zl^ti2C26LUKt3*yZw^wDy4lhwdwqQ~$uiIDC`(2{;(M*)e?9&^>4Dd^koQD_6v+8C zHB7EryE}ZpsA&D;^<&f1{T2%~^08a#zkAZMzQN^|6e(Yn!&5-cz1)_}>X5FZgEF2Q zv?femvk^ZwfdkT!tz7Y?d~$yoo9FXt8)=)_URWm|?^0S1^`K>h5WRY(H@tWLM#$%4 zKf;#=fdd4tztO=VHx;5H!@=E41>p8Tyw7*fMWm#p7Ky1Ze;#S}p4FPM*S|lA_tn() zNcPS<&vH_r8-cH)hi^0d_HWFgi}W$J`5-Fl>b90xTfug6E9Ed)qK@n%i@wH9kYl|O zZgr;oUE)1nX>{FWafv191vee203&bqXG&Ne1Fn#@H%*^za?I9J*eBQd4yfA_vSsx;hmCSlbF*GzNd6H_+OQ_mon zdX;D0O?{=YVtlQYzmtlv^smRYlkZQ&8JHMOp#)_dmAXt*fSv26|LP&}A-;GI83;MD zB3xM>EFuj`EXWBnyAc51*kgTt9SsYGuB#-LyT`L3uBdS`sFn|&m$&Hejur&l_oc*+ zKUsSO%d6ip9}A$b1^st56?jp=$iU-+kQCj#3e^(wA7#*6za8gbzTY?4F(zZBDvnrx zF`GPOc{Af|mf^W|05LkvBIpCx6b(jr_aBpb#0y7FP3;H*+`I7ce3jlCaSszsA-^7Z z+bR3+!z5;fKJ~*m<~0)5XHpjAD!`IjVnuqg`C@4inXTXLA6Z_ckSS#NRgdMDH;Ri( zJkIT@v|pBA8d*!jVj+Tz_XqG)Xcee3&SF0_fPAH9#HP9tF-DRI#|6iiHG9RxO-iw=SKckjrJ6liPj7J$)<%)cJXM4$;pizLL$P_7BvYeEh?X_^(=awEigLD z+w#2Uj_gaZ*Dm1KY+J*G+*%y3c2^T2e|%cq_YO{#@R$IUGHPDInmF$#&7H=tX0Hz0 z$8USRe!a=B-H%;58?O}98=cqcgP>V804i}p*dE4OL;V=`mkC8QiLjH_rd@{tSi-;37Fzh66F1_|rOsXlkaOJh6cH&Rz(oOZ}e+@{-2 znu!uueAY((rKpb0WZ~)JEGP{|>Jn-bGfi|j(#7oJ!+rEQTgDHf*QT?q=BM#>+vMeI zkvc}f$NQf!h5!9X)!Ah7`1(--m{BaJM~9)ngbao~te9c736_ZfQA~Gl1ewa@n9F_z z7hc|5+a04pne8v8>1(_0Np5u~Ow_q~8lDY7xbk{x#94xMv22GxF|42gX>r{)s2k__ zRO{-{>wSY|tCY1w3UPR`S7okAopAUwe-Rl$sXX&FNpr?L#O8K+5H{-+VF)fX9#+y6F zjOXyMK=p3F07unP=!nf;pjdB zbIq3G6Gbw|&@Z=-@z5(+3q5`K=Ec>l0^BdMMO@tjJ{b7pq2=w2z71zGRkJ_$7?&MT zP)JVlm2OTO@-zId+uPz08bL+=9}zI2_u6KW_z1U=q7Dv+3A_tV5)&PtkXW5Pe*PI+ zMV>rz!ySck3l`Rtd>vC)r=wx|iYv1W*=*^D^#XRgh8s2n?HPQ#AIHgUx2k}BM0ESx zR)y=m5`Wow$X1=ZC9^y$JG=9PE0{NFmLc^rR|>`cp#+2!RtaXU3a;r|%@ga0B~b8h zlk42rNJ5*gR(Em=Ca*_u&M$hx1;*%fPb)a|Hu9kNq;WA(t;K|~8?`20XC~+5wpd4u zaGiohN*qyf;stX!6l8*Wa(`K_UG~^mbxMq(-eL?H7?^Jrt)n&znW$afaH9|>Iz6E2I*$nz^Ht%Is(ByuoDbxgoN$0QcJAWLIDIKOD$3c{!Xh`9{Wx{&H4k1r_4H>KT{CL^ zYHLgqe(%rf-siamiF~ADj0(>}giD&_G~)&rwRm{}Ws+#-TP&=2iQ~$skfQHSMI6%O zAp=-fYvum&>Hb$_V^O!1i?OEzjOB(ces|Z)JJRI9JCgr-3=gjDC&iqwj*Q`owMz%m z0S{3T;A@XyU}OxPl3%r^RvYYfE_a8yT*n(NGM-X1bgP+YHF%H8jT)N6Gp)u19g@(` zq7}&QVn;@xgLObQC+%}U&O$XqJK$55yOH(>>4<%W%Vl3dOuaDL zn1d20d$DJvbwzXdnvI#F0@DP;Vwt{Jsz$G!|H`W0J161P7p%@3i$E%Su$1!$4$iu( zv}&A2^EKV#b^LLK8Jw%TXy!uZ=1IhbeF(6z#m#!YC0*Zxn%nAZYNPFJ9 z)lcdXqVH=PyXWRCh6sbtx*^Z36LW9MATUuiV9Vmtr{>f;jhq;ol{(u`?LO#2A$b6d=}dNX=;AZZ1J@H_rwA^`TYS>ZLhMNsI>Khl)B5pnm#ZTo{5fvY@wz`&}}S-CdaMOh$E5W zfiKIs*&>nQd-`0<`*2aaT0#9`6}tWLIg4&wTAJ|pSzap2$HGr4Eig=5C}^X=EeXlI z8;ob3_d4F0ocFLJ((|hm8gS)zHm(>}pOIzB9_dRMNiEI7E#}<*y&^HeOr1t)Cg4I> z99K)KJ&9pSwetrXnB-+FtS(jC*G8^U3BL=Fp)nCSvpX4Ne)L1>H#{5bX*gjrpBh7# zSWbhdPwO{_13fS zMVDGJnwncv4->0#h8&>p(-cVc`9%w7JCIfUOF|;3D@8=n089xgl$B9E4f4%J!^HN~ zeGjR5H2ATP!!UJDLv!5zZn?JHQ%N=&6vWss(-h(Ne6v@G=V-%8+Z>tDNg`>2<+Y;a z%FMgW!d%eNi{ZJ5KL$7;AMwV-NgnS?`!?pZ{d^G$wg5U-DWO_EH={Ek=vo)%@7)=K zh(!AtRx2beZ;RKTSr?j`nnB6ZPmVrsSqfd&svwGOKALa|7~hnDLK_?$gxi=O0Q^Fx zS7qLx3WcItr01~4NX%NI)|UiWN{`3a$0%f`o3$E~3!gatPE_MB`UtQp>_Rj1#gG6r|n_awL#!k1@t?Q@F(O z8B@207a(9ELa1|GZaW5C$cE`rQS4PEB}~%mh59HhQO$coIMk8GjkCI}3yr)H+GR#k zG_G9k^80dPVwM>A)!Co#K3?jkcX3O8{umH}T<}IE>=qq8PoDl81KOyjp;=Ty=@N_Z z<;jPg<_sQHcXXeo(f)bT(pFAFbS_X&;{~&rA3`I3Qy2iZ07C<#UpD)6(($)IXR& zLNQT}5)#|1J!T8gq?qHfH->z|M^pa#(v&W@j0YLk?(v*(2(~SBf;{AJ+ty+K^G((t z*P(4C$m?MBx*|wK{&RiVcW0$J?>}4)LB@p})6Enb6aV$7-W&S6lQsQ4WS^*(5kl*8obqnHC5WNueclRiB6$gO1oHRI84YLuVUlcNQ^4654K@;kD)n zn+ny96ho%PY~Yv&ThI^X6%`kJ0Vt=srEX8T$ zD=$_ux=y=m#c5d@_x)i}F$pcO1YLiLptHr3Nli5ii*EL)P9}#(R; zYA%K_H5X@#$ePt@rmM7ww%7}jzR{Eh^z{y>iD$A{k39`|IQ?=-q-;@y$2i*RRUp7} zgeL+C%?5Lj4$KN2)sT=c+P@I7GCJ;7ckYkPtY(6IEfgZdzD;phep6+H~oDZH1ZuPS6Nv7$ni;z9R9!g>&a3WN&+T>Rg0|TaU>>mgA zO-`Cfg11XC1l^yzBVLPC9KNzgIdaZ^lB62N0SLItDOl{q~ z&TJAtPzec7YjRrYys}SVP=6Ze8o^SXe>d_yO!FxV%t!E4>TQ3xY_?F*(b?;g3(sRq zhnG4FY?NVQidf~edxsCmx#z9=esIlVQ))z(s#gjTRt&H4&p2W8A!v4GHVtQ+YOQ;P z^5p2f(QwG;PVtZ>W4iiScbY22-e6#djuxV?lHY;I-Nt&Km!Dt01UlHbZGA*ukHL?q z0R4E;w8R@;J*snyqNpuTYbtZqW9Se27rSBQ3z22D zPG|mE8&_~9C86aClgz#kr2h8-ud&K>Sc9hW*V@RyIGLB2ZzsQ$yWrHPY-8p`K|+!6 z-Q-2pu;X-IiwzKl@@V4)SycWpr}w=aXC1>|z7?JIdLR4VKxoZq>PBC&)VSS`k&~0N z+`$>{(Zd0&A`1hkqB~`#zyn#LW&`Q^O10(4b><&ku_B18gRcWgj>L8z2y4h3+M>PP zL$k0NQ%N>7T{~?OW*gV+-i1wGvumJtk^8XUACQPUdK+V}BR`fH>?K5P zZRTmXzd!Mc`HB9Svn}_v?}p-PlxTOiXWND}y5of3l1vA>l8l~aWoPjm$>@@Gd9JSI zc4=7e|CJsOXcO+YTMhJa!9_&r<*(8@ZYtv1&z>GgiEQuiI^b4X(WG3(ME3j^(3F?G zSZ3qii4uFgU#MU)^ADxAD%vXMvqjXjZmf9Wf=y(-<$lzg`+Zyeb}urmlRi7=`tY;P z9_vZGO5lhYJq{Q6tB(5`p4Rq*9@%HJExJgO`vSLv_|_evOPl~Hq--FkzL zX53^%-DrO*;7yW*<(SfuiXN+Yp}P)q(xFluD=v~3@#q$OnbsB3HU(b9F)w$SDPQ;o zBXls?uaGfJ4M#%vWYM0TojnMkO;d&552vaubc;O=Wc_;yJ4$T!ly(MCvjGZR+WWh| z{v)6QTGIVOTq8}qx50>iO5Zj(yy&QoA+`(Sg{00~?-z?a*8+`@a#9?d3b0lc*LbZl z!gNTczs%EWk||$a9bMqB5j`S@HRvTEX;nH+3!4??swEZojg*JoAw0Luu3(s(eQ6W4 z`1< z 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

    tOp%4bFHS1j*r4?YBHm| z&!Ff-FGP8(De3vMu%Tfl2f%hPA^S7ztZil={KO4AkN+tjUqSBghuw{E(Vm(I;C4kh bk#9wi!ikl0CTsIxz>l1ivSgX~yN~}Lba css` width: 100%; - ${Theme.typography.headline3} + ${Theme.typography.body2} font-weight: bold; `; @@ -34,6 +34,7 @@ export const roundVoteResultContainer = css` export const categoryContainer = css` display: flex; justify-content: space-between; + gap: 0.8rem; font-weight: bold; font-size: 1.4rem; @@ -90,7 +91,12 @@ export const noVoteText = css` justify-content: center; align-items: center; height: 8vh; - ${Theme.typography.headline2} + ${Theme.typography.headline3} +`; + +export const angryImage = css` + width: 16rem; + height: 14rem; `; export const resultTextStyle = (isActiveGroupTab: boolean) => css` diff --git a/frontend/src/components/TabContentContainer/TabContentContainer.tsx b/frontend/src/components/TabContentContainer/TabContentContainer.tsx index ad9640f4..e4627de4 100644 --- a/frontend/src/components/TabContentContainer/TabContentContainer.tsx +++ b/frontend/src/components/TabContentContainer/TabContentContainer.tsx @@ -2,6 +2,7 @@ import { useNavigate, useParams } from 'react-router-dom'; import { alertText, + angryImage, barWrapperStyle, buttonStyle, categoryContainer, @@ -16,7 +17,7 @@ import { } from './TabContentContainer.styled'; import useTotalCountAnimation from '../RoundVoteContainer/RoundVoteContainer.hook'; -import DdangkongTimer from '@/assets/images/ddangkongTimer.png'; +import AngryDdangkong from '@/assets/images/angryDdangkong.png'; import { ROUTES } from '@/constants/routes'; import useBalanceContentQuery from '@/hooks/useBalanceContentQuery'; import useMyGameStatus from '@/hooks/useMyGameStatus'; @@ -93,7 +94,7 @@ const TabContentContainer = ({ isGroupTabActive }: TabContentContainerProps) => ) : (

    - + 화난 땅콩 아무도 투표하지 않으셨네요 :{`)`}
    )} From c7b3ca5d2bcde388da423d4117c9d3eae8d040be Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Wed, 14 Aug 2024 19:41:00 +0900 Subject: [PATCH 0687/1013] =?UTF-8?q?test:=20=EC=95=84=EB=AC=B4=EB=8F=84?= =?UTF-8?q?=20=ED=88=AC=ED=91=9C=ED=95=98=EC=A7=80=20=EC=95=8A=EC=9D=84=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20=ED=86=B5=EA=B3=84=20=EB=8C=80=EC=8B=A0=20?= =?UTF-8?q?=EB=8B=A4=EB=A5=B8=20=ED=85=8D=EC=8A=A4=ED=8A=B8=EB=A5=BC=20?= =?UTF-8?q?=EB=B3=B4=EC=97=AC=EC=A3=BC=EB=8A=94=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1=20#155?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TabContentContainer.test.tsx | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/TabContentContainer/TabContentContainer.test.tsx b/frontend/src/components/TabContentContainer/TabContentContainer.test.tsx index 926c7268..2e26e70d 100644 --- a/frontend/src/components/TabContentContainer/TabContentContainer.test.tsx +++ b/frontend/src/components/TabContentContainer/TabContentContainer.test.tsx @@ -1,11 +1,14 @@ import { renderHook, screen, waitFor } from '@testing-library/react'; +import { http, HttpResponse } from 'msw'; import TabContentContainer from './TabContentContainer'; +import { MOCK_API_URL } from '@/constants/url'; import useRoundVoteResultQuery from '@/hooks/useRoundVoteResultQuery'; +import ROUND_VOTE_RESULT from '@/mocks/data/roundVoteResult.json'; +import { server } from '@/mocks/server'; import { customRender, wrapper } from '@/test-utils'; - describe('TabContentContainer 컴포넌트 테스트', () => { it('라운드 결과 그룹원들이 선택한 퍼센트를 카운팅 애니메이션으로 보여준다.', async () => { customRender(); @@ -29,4 +32,21 @@ describe('TabContentContainer 컴포넌트 테스트', () => { expect(result.current.data?.group.secondOption.percent).toBe(27); }); }); + + it('아무도 투표하지 않아 모두 기권인 경우, "아무도 투표하지 않으셨네요 :)" 텍스트를 보여준다.', async () => { + ROUND_VOTE_RESULT.group.firstOption.percent = 0; + ROUND_VOTE_RESULT.group.secondOption.percent = 0; + + server.use( + http.get(MOCK_API_URL.roundVoteResult, () => { + return HttpResponse.json(ROUND_VOTE_RESULT); + }), + ); + + customRender(); + + await waitFor(() => { + expect(screen.getByText('아무도 투표하지 않으셨네요 :)')).toBeInTheDocument(); + }); + }); }); From 69f2550c14c8a5eb91c45ce5d69a08b05d8b5903 Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 15 Aug 2024 12:25:09 +0900 Subject: [PATCH 0688/1013] =?UTF-8?q?fix:=20=EC=99=BC=EC=AA=BD=20=EC=98=B5?= =?UTF-8?q?=EC=85=98=20=EC=84=A0=ED=83=9D=20=EC=8B=9C=200%=20=ED=85=8D?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EA=B0=80=20=EB=82=A8=EC=95=84=EC=9E=88?= =?UTF-8?q?=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0=20#155?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TabContentContainer/TabContentContainer.styled.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/src/components/TabContentContainer/TabContentContainer.styled.ts b/frontend/src/components/TabContentContainer/TabContentContainer.styled.ts index ae0a303b..b1e276b5 100644 --- a/frontend/src/components/TabContentContainer/TabContentContainer.styled.ts +++ b/frontend/src/components/TabContentContainer/TabContentContainer.styled.ts @@ -62,6 +62,7 @@ export const barWrapper = css` export const firstBar = (percent: number, isBigFirstOption?: boolean) => css` ${barWrapper} + overflow: hidden; width: ${percent}%; border-radius: 1.6rem 0 0 1.6rem; @@ -72,6 +73,7 @@ export const firstBar = (percent: number, isBigFirstOption?: boolean) => css` export const secondBar = (percent: number, isBigFirstOption?: boolean) => css` ${barWrapper} + overflow: hidden; width: ${percent}%; border-radius: 0 1.6rem 1.6rem 0; From b5f14e2c0b74e2d7dfb3e708e4cee594a9779605 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 15 Aug 2024 13:38:46 +0900 Subject: [PATCH 0689/1013] =?UTF-8?q?refactor:=20DTO=20=EC=9C=84=EC=B9=98?= =?UTF-8?q?=20service=20layer=EB=A1=9C=20=EC=9D=B4=EB=8F=99=20#173?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/BalanceContentController.java | 2 +- .../controller/balance/room/RoomController.java | 8 ++++---- .../balance/room/dto/RoomJoinResponse.java | 9 --------- .../balance/vote/BalanceVoteController.java | 8 ++++---- .../vote/dto/BalanceVoteResultResponse.java | 10 ---------- .../balance/content/BalanceContentService.java | 2 +- .../content/dto/BalanceContentGroupResponse.java | 4 ++-- .../content/dto/BalanceContentResponse.java | 4 ++-- .../content/dto/BalanceContentTotalResponse.java | 4 ++-- .../option/dto/BalanceOptionGroupResponse.java | 2 +- .../option/dto/BalanceOptionResponse.java | 2 +- .../option/dto/BalanceOptionTotalResponse.java | 2 +- .../dto/VoteFinishedResponse.java | 2 +- .../service/balance/room/RoomService.java | 8 ++++---- .../balance/room/dto/RoomInfoResponse.java | 4 ++-- .../balance/room/dto/RoomJoinRequest.java | 2 +- .../balance/room/dto/RoomJoinResponse.java | 9 +++++++++ .../balance/room/dto/RoomSettingRequest.java | 2 +- .../balance/room/dto/RoomSettingResponse.java | 2 +- .../service/balance/vote/BalanceVoteService.java | 12 ++++++------ .../balance/vote/dto/BalanceVoteRequest.java | 2 +- .../balance/vote/dto/BalanceVoteResponse.java | 2 +- .../vote/dto/BalanceVoteResultResponse.java | 10 ++++++++++ .../member/dto/MemberResponse.java | 2 +- .../content/BalanceContentControllerTest.java | 4 ++-- .../balance/room/RoomControllerTest.java | 9 ++++----- .../balance/vote/BalanceVoteControllerTest.java | 6 +++--- .../content/BalanceContentDocumentationTest.java | 4 ++-- .../balance/room/RoomDocumentationTest.java | 12 ++++++------ .../vote/BalanceVoteDocumentationTest.java | 16 ++++++++-------- .../content/BalanceContentServiceTest.java | 4 ++-- .../service/balance/room/RoomServiceTest.java | 10 +++++----- .../balance/vote/BalanceVoteServiceTest.java | 16 ++++++++-------- 33 files changed, 97 insertions(+), 98 deletions(-) delete mode 100644 backend/src/main/java/ddangkong/controller/balance/room/dto/RoomJoinResponse.java delete mode 100644 backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteResultResponse.java rename backend/src/main/java/ddangkong/{controller => service}/balance/content/dto/BalanceContentGroupResponse.java (87%) rename backend/src/main/java/ddangkong/{controller => service}/balance/content/dto/BalanceContentResponse.java (89%) rename backend/src/main/java/ddangkong/{controller => service}/balance/content/dto/BalanceContentTotalResponse.java (86%) rename backend/src/main/java/ddangkong/{controller => service}/balance/option/dto/BalanceOptionGroupResponse.java (94%) rename backend/src/main/java/ddangkong/{controller => service}/balance/option/dto/BalanceOptionResponse.java (86%) rename backend/src/main/java/ddangkong/{controller => service}/balance/option/dto/BalanceOptionTotalResponse.java (91%) rename backend/src/main/java/ddangkong/service/balance/{vote => option}/dto/VoteFinishedResponse.java (87%) rename backend/src/main/java/ddangkong/{controller => service}/balance/room/dto/RoomInfoResponse.java (86%) rename backend/src/main/java/ddangkong/{controller => service}/balance/room/dto/RoomJoinRequest.java (73%) create mode 100644 backend/src/main/java/ddangkong/service/balance/room/dto/RoomJoinResponse.java rename backend/src/main/java/ddangkong/{controller => service}/balance/room/dto/RoomSettingRequest.java (77%) rename backend/src/main/java/ddangkong/{controller => service}/balance/room/dto/RoomSettingResponse.java (88%) rename backend/src/main/java/ddangkong/{controller => service}/balance/vote/dto/BalanceVoteRequest.java (91%) rename backend/src/main/java/ddangkong/{controller => service}/balance/vote/dto/BalanceVoteResponse.java (82%) create mode 100644 backend/src/main/java/ddangkong/service/balance/vote/dto/BalanceVoteResultResponse.java rename backend/src/main/java/ddangkong/{controller/balance => service}/member/dto/MemberResponse.java (84%) diff --git a/backend/src/main/java/ddangkong/controller/balance/content/BalanceContentController.java b/backend/src/main/java/ddangkong/controller/balance/content/BalanceContentController.java index f8c9fb27..0e522f9b 100644 --- a/backend/src/main/java/ddangkong/controller/balance/content/BalanceContentController.java +++ b/backend/src/main/java/ddangkong/controller/balance/content/BalanceContentController.java @@ -1,6 +1,6 @@ package ddangkong.controller.balance.content; -import ddangkong.controller.balance.content.dto.BalanceContentResponse; +import ddangkong.service.balance.content.dto.BalanceContentResponse; import ddangkong.service.balance.content.BalanceContentService; import jakarta.validation.constraints.Positive; import lombok.RequiredArgsConstructor; diff --git a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java index fc03a21e..40a07e92 100644 --- a/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java +++ b/backend/src/main/java/ddangkong/controller/balance/room/RoomController.java @@ -1,10 +1,10 @@ package ddangkong.controller.balance.room; import ddangkong.aop.logging.Polling; -import ddangkong.controller.balance.room.dto.RoomInfoResponse; -import ddangkong.controller.balance.room.dto.RoomJoinRequest; -import ddangkong.controller.balance.room.dto.RoomJoinResponse; -import ddangkong.controller.balance.room.dto.RoomSettingRequest; +import ddangkong.service.balance.room.dto.RoomInfoResponse; +import ddangkong.service.balance.room.dto.RoomJoinRequest; +import ddangkong.service.balance.room.dto.RoomJoinResponse; +import ddangkong.service.balance.room.dto.RoomSettingRequest; import ddangkong.service.balance.room.RoomService; import ddangkong.service.balance.room.dto.RoundFinishedResponse; import jakarta.validation.Valid; diff --git a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomJoinResponse.java b/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomJoinResponse.java deleted file mode 100644 index 82d48125..00000000 --- a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomJoinResponse.java +++ /dev/null @@ -1,9 +0,0 @@ -package ddangkong.controller.balance.room.dto; - -import ddangkong.controller.balance.member.dto.MemberResponse; - -public record RoomJoinResponse( - Long roomId, - MemberResponse member -) { -} diff --git a/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java b/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java index 9815ba9d..b323ca40 100644 --- a/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java +++ b/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java @@ -1,11 +1,11 @@ package ddangkong.controller.balance.vote; import ddangkong.aop.logging.Polling; -import ddangkong.controller.balance.vote.dto.BalanceVoteRequest; -import ddangkong.controller.balance.vote.dto.BalanceVoteResponse; -import ddangkong.controller.balance.vote.dto.BalanceVoteResultResponse; +import ddangkong.service.balance.vote.dto.BalanceVoteRequest; +import ddangkong.service.balance.vote.dto.BalanceVoteResponse; +import ddangkong.service.balance.vote.dto.BalanceVoteResultResponse; import ddangkong.service.balance.vote.BalanceVoteService; -import ddangkong.service.balance.vote.dto.VoteFinishedResponse; +import ddangkong.service.balance.option.dto.VoteFinishedResponse; import jakarta.validation.Valid; import jakarta.validation.constraints.Positive; import lombok.RequiredArgsConstructor; diff --git a/backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteResultResponse.java b/backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteResultResponse.java deleted file mode 100644 index e985c004..00000000 --- a/backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteResultResponse.java +++ /dev/null @@ -1,10 +0,0 @@ -package ddangkong.controller.balance.vote.dto; - -import ddangkong.controller.balance.content.dto.BalanceContentGroupResponse; -import ddangkong.controller.balance.content.dto.BalanceContentTotalResponse; - -public record BalanceVoteResultResponse( - BalanceContentGroupResponse group, - BalanceContentTotalResponse total -) { -} diff --git a/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java b/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java index 239ea9b2..48d4ced5 100644 --- a/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java +++ b/backend/src/main/java/ddangkong/service/balance/content/BalanceContentService.java @@ -1,6 +1,6 @@ package ddangkong.service.balance.content; -import ddangkong.controller.balance.content.dto.BalanceContentResponse; +import ddangkong.service.balance.content.dto.BalanceContentResponse; import ddangkong.domain.balance.option.BalanceOptionRepository; import ddangkong.domain.balance.option.BalanceOptions; import ddangkong.domain.balance.room.Room; diff --git a/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentGroupResponse.java b/backend/src/main/java/ddangkong/service/balance/content/dto/BalanceContentGroupResponse.java similarity index 87% rename from backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentGroupResponse.java rename to backend/src/main/java/ddangkong/service/balance/content/dto/BalanceContentGroupResponse.java index 44684a72..13f74200 100644 --- a/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentGroupResponse.java +++ b/backend/src/main/java/ddangkong/service/balance/content/dto/BalanceContentGroupResponse.java @@ -1,6 +1,6 @@ -package ddangkong.controller.balance.content.dto; +package ddangkong.service.balance.content.dto; -import ddangkong.controller.balance.option.dto.BalanceOptionGroupResponse; +import ddangkong.service.balance.option.dto.BalanceOptionGroupResponse; import ddangkong.domain.balance.option.BalanceOptions; import ddangkong.domain.balance.vote.BalanceVote; import java.util.List; diff --git a/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentResponse.java b/backend/src/main/java/ddangkong/service/balance/content/dto/BalanceContentResponse.java similarity index 89% rename from backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentResponse.java rename to backend/src/main/java/ddangkong/service/balance/content/dto/BalanceContentResponse.java index 1d70803c..6f9c4f55 100644 --- a/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentResponse.java +++ b/backend/src/main/java/ddangkong/service/balance/content/dto/BalanceContentResponse.java @@ -1,6 +1,6 @@ -package ddangkong.controller.balance.content.dto; +package ddangkong.service.balance.content.dto; -import ddangkong.controller.balance.option.dto.BalanceOptionResponse; +import ddangkong.service.balance.option.dto.BalanceOptionResponse; import ddangkong.domain.balance.content.Category; import ddangkong.domain.balance.option.BalanceOptions; import ddangkong.domain.balance.room.RoomContent; diff --git a/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentTotalResponse.java b/backend/src/main/java/ddangkong/service/balance/content/dto/BalanceContentTotalResponse.java similarity index 86% rename from backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentTotalResponse.java rename to backend/src/main/java/ddangkong/service/balance/content/dto/BalanceContentTotalResponse.java index b84ed75d..2ba987c9 100644 --- a/backend/src/main/java/ddangkong/controller/balance/content/dto/BalanceContentTotalResponse.java +++ b/backend/src/main/java/ddangkong/service/balance/content/dto/BalanceContentTotalResponse.java @@ -1,6 +1,6 @@ -package ddangkong.controller.balance.content.dto; +package ddangkong.service.balance.content.dto; -import ddangkong.controller.balance.option.dto.BalanceOptionTotalResponse; +import ddangkong.service.balance.option.dto.BalanceOptionTotalResponse; import ddangkong.domain.balance.option.BalanceOptions; public record BalanceContentTotalResponse( diff --git a/backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionGroupResponse.java b/backend/src/main/java/ddangkong/service/balance/option/dto/BalanceOptionGroupResponse.java similarity index 94% rename from backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionGroupResponse.java rename to backend/src/main/java/ddangkong/service/balance/option/dto/BalanceOptionGroupResponse.java index ee38a279..9e0e7ed2 100644 --- a/backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionGroupResponse.java +++ b/backend/src/main/java/ddangkong/service/balance/option/dto/BalanceOptionGroupResponse.java @@ -1,4 +1,4 @@ -package ddangkong.controller.balance.option.dto; +package ddangkong.service.balance.option.dto; import ddangkong.domain.balance.option.BalanceOption; import ddangkong.domain.balance.vote.BalanceVote; diff --git a/backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionResponse.java b/backend/src/main/java/ddangkong/service/balance/option/dto/BalanceOptionResponse.java similarity index 86% rename from backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionResponse.java rename to backend/src/main/java/ddangkong/service/balance/option/dto/BalanceOptionResponse.java index a2c0f788..8e205be5 100644 --- a/backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionResponse.java +++ b/backend/src/main/java/ddangkong/service/balance/option/dto/BalanceOptionResponse.java @@ -1,4 +1,4 @@ -package ddangkong.controller.balance.option.dto; +package ddangkong.service.balance.option.dto; import ddangkong.domain.balance.option.BalanceOption; diff --git a/backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionTotalResponse.java b/backend/src/main/java/ddangkong/service/balance/option/dto/BalanceOptionTotalResponse.java similarity index 91% rename from backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionTotalResponse.java rename to backend/src/main/java/ddangkong/service/balance/option/dto/BalanceOptionTotalResponse.java index e658974c..fdcd11f4 100644 --- a/backend/src/main/java/ddangkong/controller/balance/option/dto/BalanceOptionTotalResponse.java +++ b/backend/src/main/java/ddangkong/service/balance/option/dto/BalanceOptionTotalResponse.java @@ -1,4 +1,4 @@ -package ddangkong.controller.balance.option.dto; +package ddangkong.service.balance.option.dto; import ddangkong.domain.balance.option.BalanceOption; diff --git a/backend/src/main/java/ddangkong/service/balance/vote/dto/VoteFinishedResponse.java b/backend/src/main/java/ddangkong/service/balance/option/dto/VoteFinishedResponse.java similarity index 87% rename from backend/src/main/java/ddangkong/service/balance/vote/dto/VoteFinishedResponse.java rename to backend/src/main/java/ddangkong/service/balance/option/dto/VoteFinishedResponse.java index 13a3c31f..abf1db94 100644 --- a/backend/src/main/java/ddangkong/service/balance/vote/dto/VoteFinishedResponse.java +++ b/backend/src/main/java/ddangkong/service/balance/option/dto/VoteFinishedResponse.java @@ -1,4 +1,4 @@ -package ddangkong.service.balance.vote.dto; +package ddangkong.service.balance.option.dto; public record VoteFinishedResponse( boolean isFinished diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index 599d70ed..454c822a 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -1,9 +1,9 @@ package ddangkong.service.balance.room; -import ddangkong.controller.balance.member.dto.MemberResponse; -import ddangkong.controller.balance.room.dto.RoomInfoResponse; -import ddangkong.controller.balance.room.dto.RoomJoinResponse; -import ddangkong.controller.balance.room.dto.RoomSettingRequest; +import ddangkong.service.member.dto.MemberResponse; +import ddangkong.service.balance.room.dto.RoomInfoResponse; +import ddangkong.service.balance.room.dto.RoomJoinResponse; +import ddangkong.service.balance.room.dto.RoomSettingRequest; import ddangkong.domain.balance.content.BalanceContent; import ddangkong.domain.balance.content.BalanceContentRepository; import ddangkong.domain.balance.content.Category; diff --git a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomInfoResponse.java b/backend/src/main/java/ddangkong/service/balance/room/dto/RoomInfoResponse.java similarity index 86% rename from backend/src/main/java/ddangkong/controller/balance/room/dto/RoomInfoResponse.java rename to backend/src/main/java/ddangkong/service/balance/room/dto/RoomInfoResponse.java index a29e61cb..fbc71a88 100644 --- a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomInfoResponse.java +++ b/backend/src/main/java/ddangkong/service/balance/room/dto/RoomInfoResponse.java @@ -1,6 +1,6 @@ -package ddangkong.controller.balance.room.dto; +package ddangkong.service.balance.room.dto; -import ddangkong.controller.balance.member.dto.MemberResponse; +import ddangkong.service.member.dto.MemberResponse; import ddangkong.domain.balance.room.Room; import ddangkong.domain.member.Member; import java.util.List; diff --git a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomJoinRequest.java b/backend/src/main/java/ddangkong/service/balance/room/dto/RoomJoinRequest.java similarity index 73% rename from backend/src/main/java/ddangkong/controller/balance/room/dto/RoomJoinRequest.java rename to backend/src/main/java/ddangkong/service/balance/room/dto/RoomJoinRequest.java index e2db6582..fe9c6745 100644 --- a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomJoinRequest.java +++ b/backend/src/main/java/ddangkong/service/balance/room/dto/RoomJoinRequest.java @@ -1,4 +1,4 @@ -package ddangkong.controller.balance.room.dto; +package ddangkong.service.balance.room.dto; import jakarta.validation.constraints.NotBlank; diff --git a/backend/src/main/java/ddangkong/service/balance/room/dto/RoomJoinResponse.java b/backend/src/main/java/ddangkong/service/balance/room/dto/RoomJoinResponse.java new file mode 100644 index 00000000..523c5263 --- /dev/null +++ b/backend/src/main/java/ddangkong/service/balance/room/dto/RoomJoinResponse.java @@ -0,0 +1,9 @@ +package ddangkong.service.balance.room.dto; + +import ddangkong.service.member.dto.MemberResponse; + +public record RoomJoinResponse( + Long roomId, + MemberResponse member +) { +} diff --git a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSettingRequest.java b/backend/src/main/java/ddangkong/service/balance/room/dto/RoomSettingRequest.java similarity index 77% rename from backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSettingRequest.java rename to backend/src/main/java/ddangkong/service/balance/room/dto/RoomSettingRequest.java index 9ab30d01..65b22f69 100644 --- a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSettingRequest.java +++ b/backend/src/main/java/ddangkong/service/balance/room/dto/RoomSettingRequest.java @@ -1,4 +1,4 @@ -package ddangkong.controller.balance.room.dto; +package ddangkong.service.balance.room.dto; import ddangkong.domain.balance.content.Category; diff --git a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSettingResponse.java b/backend/src/main/java/ddangkong/service/balance/room/dto/RoomSettingResponse.java similarity index 88% rename from backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSettingResponse.java rename to backend/src/main/java/ddangkong/service/balance/room/dto/RoomSettingResponse.java index d8eed61a..1d14d4e3 100644 --- a/backend/src/main/java/ddangkong/controller/balance/room/dto/RoomSettingResponse.java +++ b/backend/src/main/java/ddangkong/service/balance/room/dto/RoomSettingResponse.java @@ -1,4 +1,4 @@ -package ddangkong.controller.balance.room.dto; +package ddangkong.service.balance.room.dto; import ddangkong.domain.balance.content.Category; import ddangkong.domain.balance.room.Room; diff --git a/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java b/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java index d75d9863..d4c33742 100644 --- a/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java +++ b/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java @@ -1,10 +1,10 @@ package ddangkong.service.balance.vote; -import ddangkong.controller.balance.content.dto.BalanceContentGroupResponse; -import ddangkong.controller.balance.content.dto.BalanceContentTotalResponse; -import ddangkong.controller.balance.vote.dto.BalanceVoteRequest; -import ddangkong.controller.balance.vote.dto.BalanceVoteResponse; -import ddangkong.controller.balance.vote.dto.BalanceVoteResultResponse; +import ddangkong.service.balance.content.dto.BalanceContentGroupResponse; +import ddangkong.service.balance.content.dto.BalanceContentTotalResponse; +import ddangkong.service.balance.vote.dto.BalanceVoteRequest; +import ddangkong.service.balance.vote.dto.BalanceVoteResponse; +import ddangkong.service.balance.vote.dto.BalanceVoteResultResponse; import ddangkong.domain.balance.content.BalanceContent; import ddangkong.domain.balance.content.BalanceContentRepository; import ddangkong.domain.balance.option.BalanceOption; @@ -19,7 +19,7 @@ import ddangkong.domain.member.Member; import ddangkong.domain.member.MemberRepository; import ddangkong.exception.BadRequestException; -import ddangkong.service.balance.vote.dto.VoteFinishedResponse; +import ddangkong.service.balance.option.dto.VoteFinishedResponse; import java.time.Clock; import java.time.LocalDateTime; import java.util.List; diff --git a/backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteRequest.java b/backend/src/main/java/ddangkong/service/balance/vote/dto/BalanceVoteRequest.java similarity index 91% rename from backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteRequest.java rename to backend/src/main/java/ddangkong/service/balance/vote/dto/BalanceVoteRequest.java index ab24cccd..b26677d4 100644 --- a/backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteRequest.java +++ b/backend/src/main/java/ddangkong/service/balance/vote/dto/BalanceVoteRequest.java @@ -1,4 +1,4 @@ -package ddangkong.controller.balance.vote.dto; +package ddangkong.service.balance.vote.dto; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Positive; diff --git a/backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteResponse.java b/backend/src/main/java/ddangkong/service/balance/vote/dto/BalanceVoteResponse.java similarity index 82% rename from backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteResponse.java rename to backend/src/main/java/ddangkong/service/balance/vote/dto/BalanceVoteResponse.java index c7e277cf..fa896a3b 100644 --- a/backend/src/main/java/ddangkong/controller/balance/vote/dto/BalanceVoteResponse.java +++ b/backend/src/main/java/ddangkong/service/balance/vote/dto/BalanceVoteResponse.java @@ -1,4 +1,4 @@ -package ddangkong.controller.balance.vote.dto; +package ddangkong.service.balance.vote.dto; import ddangkong.domain.balance.vote.BalanceVote; diff --git a/backend/src/main/java/ddangkong/service/balance/vote/dto/BalanceVoteResultResponse.java b/backend/src/main/java/ddangkong/service/balance/vote/dto/BalanceVoteResultResponse.java new file mode 100644 index 00000000..66e5598f --- /dev/null +++ b/backend/src/main/java/ddangkong/service/balance/vote/dto/BalanceVoteResultResponse.java @@ -0,0 +1,10 @@ +package ddangkong.service.balance.vote.dto; + +import ddangkong.service.balance.content.dto.BalanceContentGroupResponse; +import ddangkong.service.balance.content.dto.BalanceContentTotalResponse; + +public record BalanceVoteResultResponse( + BalanceContentGroupResponse group, + BalanceContentTotalResponse total +) { +} diff --git a/backend/src/main/java/ddangkong/controller/balance/member/dto/MemberResponse.java b/backend/src/main/java/ddangkong/service/member/dto/MemberResponse.java similarity index 84% rename from backend/src/main/java/ddangkong/controller/balance/member/dto/MemberResponse.java rename to backend/src/main/java/ddangkong/service/member/dto/MemberResponse.java index e2370e63..fa04c565 100644 --- a/backend/src/main/java/ddangkong/controller/balance/member/dto/MemberResponse.java +++ b/backend/src/main/java/ddangkong/service/member/dto/MemberResponse.java @@ -1,4 +1,4 @@ -package ddangkong.controller.balance.member.dto; +package ddangkong.service.member.dto; import ddangkong.domain.member.Member; diff --git a/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java index 9e264f26..1d942c29 100644 --- a/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/content/BalanceContentControllerTest.java @@ -3,8 +3,8 @@ import static org.assertj.core.api.Assertions.assertThat; import ddangkong.controller.BaseControllerTest; -import ddangkong.controller.balance.content.dto.BalanceContentResponse; -import ddangkong.controller.balance.option.dto.BalanceOptionResponse; +import ddangkong.service.balance.content.dto.BalanceContentResponse; +import ddangkong.service.balance.option.dto.BalanceOptionResponse; import ddangkong.domain.balance.content.Category; import io.restassured.RestAssured; import org.junit.jupiter.api.Nested; diff --git a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java index b5c7ea47..35f85c97 100644 --- a/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/room/RoomControllerTest.java @@ -4,10 +4,10 @@ import static org.junit.jupiter.api.Assertions.assertAll; import ddangkong.controller.BaseControllerTest; -import ddangkong.controller.balance.room.dto.RoomInfoResponse; -import ddangkong.controller.balance.room.dto.RoomJoinRequest; -import ddangkong.controller.balance.room.dto.RoomJoinResponse; -import ddangkong.controller.balance.room.dto.RoomSettingRequest; +import ddangkong.service.balance.room.dto.RoomInfoResponse; +import ddangkong.service.balance.room.dto.RoomJoinRequest; +import ddangkong.service.balance.room.dto.RoomJoinResponse; +import ddangkong.service.balance.room.dto.RoomSettingRequest; import ddangkong.domain.balance.content.BalanceContent; import ddangkong.domain.balance.content.Category; import ddangkong.domain.balance.room.Room; @@ -16,7 +16,6 @@ import ddangkong.service.balance.room.dto.RoundFinishedResponse; import io.restassured.RestAssured; import io.restassured.http.ContentType; -import java.util.HashMap; import java.util.Map; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; diff --git a/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java index ed215c2d..5256fe48 100644 --- a/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java @@ -7,8 +7,8 @@ import static org.assertj.core.api.Assertions.assertThat; import ddangkong.controller.BaseControllerTest; -import ddangkong.controller.balance.vote.dto.BalanceVoteRequest; -import ddangkong.controller.balance.vote.dto.BalanceVoteResponse; +import ddangkong.service.balance.vote.dto.BalanceVoteRequest; +import ddangkong.service.balance.vote.dto.BalanceVoteResponse; import ddangkong.domain.balance.content.BalanceContent; import ddangkong.domain.balance.content.Category; import ddangkong.domain.balance.option.BalanceOption; @@ -16,7 +16,7 @@ import ddangkong.domain.balance.room.RoomContent; import ddangkong.domain.balance.vote.BalanceVote; import ddangkong.domain.member.Member; -import ddangkong.service.balance.vote.dto.VoteFinishedResponse; +import ddangkong.service.balance.option.dto.VoteFinishedResponse; import ddangkong.support.annotation.FixedClock; import io.restassured.RestAssured; import io.restassured.http.ContentType; diff --git a/backend/src/test/java/ddangkong/documentation/balance/content/BalanceContentDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/content/BalanceContentDocumentationTest.java index f05c89f5..fb66bb11 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/content/BalanceContentDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/content/BalanceContentDocumentationTest.java @@ -13,8 +13,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import ddangkong.controller.balance.content.BalanceContentController; -import ddangkong.controller.balance.content.dto.BalanceContentResponse; -import ddangkong.controller.balance.option.dto.BalanceOptionResponse; +import ddangkong.service.balance.content.dto.BalanceContentResponse; +import ddangkong.service.balance.option.dto.BalanceOptionResponse; import ddangkong.documentation.BaseDocumentationTest; import ddangkong.domain.balance.content.Category; import ddangkong.service.balance.content.BalanceContentService; diff --git a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java index 7c8a7bde..843602f6 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java @@ -22,13 +22,13 @@ import static org.springframework.restdocs.request.RequestDocumentation.queryParameters; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import ddangkong.controller.balance.member.dto.MemberResponse; +import ddangkong.service.member.dto.MemberResponse; import ddangkong.controller.balance.room.RoomController; -import ddangkong.controller.balance.room.dto.RoomInfoResponse; -import ddangkong.controller.balance.room.dto.RoomJoinRequest; -import ddangkong.controller.balance.room.dto.RoomJoinResponse; -import ddangkong.controller.balance.room.dto.RoomSettingRequest; -import ddangkong.controller.balance.room.dto.RoomSettingResponse; +import ddangkong.service.balance.room.dto.RoomInfoResponse; +import ddangkong.service.balance.room.dto.RoomJoinRequest; +import ddangkong.service.balance.room.dto.RoomJoinResponse; +import ddangkong.service.balance.room.dto.RoomSettingRequest; +import ddangkong.service.balance.room.dto.RoomSettingResponse; import ddangkong.documentation.BaseDocumentationTest; import ddangkong.domain.balance.content.Category; import ddangkong.service.balance.room.RoomService; diff --git a/backend/src/test/java/ddangkong/documentation/balance/vote/BalanceVoteDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/vote/BalanceVoteDocumentationTest.java index 4fac895e..cf8447f5 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/vote/BalanceVoteDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/vote/BalanceVoteDocumentationTest.java @@ -17,17 +17,17 @@ import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import ddangkong.controller.balance.content.dto.BalanceContentGroupResponse; -import ddangkong.controller.balance.content.dto.BalanceContentTotalResponse; -import ddangkong.controller.balance.option.dto.BalanceOptionGroupResponse; -import ddangkong.controller.balance.option.dto.BalanceOptionTotalResponse; +import ddangkong.service.balance.content.dto.BalanceContentGroupResponse; +import ddangkong.service.balance.content.dto.BalanceContentTotalResponse; +import ddangkong.service.balance.option.dto.BalanceOptionGroupResponse; +import ddangkong.service.balance.option.dto.BalanceOptionTotalResponse; import ddangkong.controller.balance.vote.BalanceVoteController; -import ddangkong.controller.balance.vote.dto.BalanceVoteRequest; -import ddangkong.controller.balance.vote.dto.BalanceVoteResponse; -import ddangkong.controller.balance.vote.dto.BalanceVoteResultResponse; +import ddangkong.service.balance.vote.dto.BalanceVoteRequest; +import ddangkong.service.balance.vote.dto.BalanceVoteResponse; +import ddangkong.service.balance.vote.dto.BalanceVoteResultResponse; import ddangkong.documentation.BaseDocumentationTest; import ddangkong.service.balance.vote.BalanceVoteService; -import ddangkong.service.balance.vote.dto.VoteFinishedResponse; +import ddangkong.service.balance.option.dto.VoteFinishedResponse; import java.util.List; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; diff --git a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java index 63e2fbe0..e02b4ea6 100644 --- a/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/content/BalanceContentServiceTest.java @@ -3,8 +3,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import ddangkong.controller.balance.content.dto.BalanceContentResponse; -import ddangkong.controller.balance.option.dto.BalanceOptionResponse; +import ddangkong.service.balance.content.dto.BalanceContentResponse; +import ddangkong.service.balance.option.dto.BalanceOptionResponse; import ddangkong.domain.balance.content.Category; import ddangkong.exception.BadRequestException; import ddangkong.service.BaseServiceTest; diff --git a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java index 1d50ad0c..01cf6dc3 100644 --- a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java @@ -4,11 +4,11 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertAll; -import ddangkong.controller.balance.member.dto.MemberResponse; -import ddangkong.controller.balance.room.dto.RoomInfoResponse; -import ddangkong.controller.balance.room.dto.RoomJoinResponse; -import ddangkong.controller.balance.room.dto.RoomSettingRequest; -import ddangkong.controller.balance.room.dto.RoomSettingResponse; +import ddangkong.service.member.dto.MemberResponse; +import ddangkong.service.balance.room.dto.RoomInfoResponse; +import ddangkong.service.balance.room.dto.RoomJoinResponse; +import ddangkong.service.balance.room.dto.RoomSettingRequest; +import ddangkong.service.balance.room.dto.RoomSettingResponse; import ddangkong.domain.balance.content.BalanceContent; import ddangkong.domain.balance.content.BalanceContentRepository; import ddangkong.domain.balance.content.Category; diff --git a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java index 40ecde39..ba93ca03 100644 --- a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java @@ -7,13 +7,13 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import ddangkong.controller.balance.content.dto.BalanceContentGroupResponse; -import ddangkong.controller.balance.content.dto.BalanceContentTotalResponse; -import ddangkong.controller.balance.option.dto.BalanceOptionGroupResponse; -import ddangkong.controller.balance.option.dto.BalanceOptionTotalResponse; -import ddangkong.controller.balance.vote.dto.BalanceVoteRequest; -import ddangkong.controller.balance.vote.dto.BalanceVoteResponse; -import ddangkong.controller.balance.vote.dto.BalanceVoteResultResponse; +import ddangkong.service.balance.content.dto.BalanceContentGroupResponse; +import ddangkong.service.balance.content.dto.BalanceContentTotalResponse; +import ddangkong.service.balance.option.dto.BalanceOptionGroupResponse; +import ddangkong.service.balance.option.dto.BalanceOptionTotalResponse; +import ddangkong.service.balance.vote.dto.BalanceVoteRequest; +import ddangkong.service.balance.vote.dto.BalanceVoteResponse; +import ddangkong.service.balance.vote.dto.BalanceVoteResultResponse; import ddangkong.domain.balance.content.BalanceContent; import ddangkong.domain.balance.content.Category; import ddangkong.domain.balance.option.BalanceOption; @@ -23,7 +23,7 @@ import ddangkong.domain.member.Member; import ddangkong.exception.BadRequestException; import ddangkong.service.BaseServiceTest; -import ddangkong.service.balance.vote.dto.VoteFinishedResponse; +import ddangkong.service.balance.option.dto.VoteFinishedResponse; import ddangkong.support.annotation.FixedClock; import java.time.LocalDateTime; import java.util.List; From 61170d888dc71a2346a1eab47584528e3e089e51 Mon Sep 17 00:00:00 2001 From: PgmJun <84304802+PgmJun@users.noreply.github.com> Date: Thu, 15 Aug 2024 13:57:16 +0900 Subject: [PATCH 0690/1013] =?UTF-8?q?refactor:=20=EC=9E=98=EB=AA=BB=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=EB=90=9C=20=ED=8C=A8=ED=82=A4=EC=A7=80=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EC=88=98=EC=A0=95=20#173?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../balance/vote/BalanceVoteController.java | 4 ++-- .../{ => balance}/member/dto/MemberResponse.java | 2 +- .../service/balance/room/RoomService.java | 8 ++++---- .../balance/room/dto/RoomInfoResponse.java | 2 +- .../balance/room/dto/RoomJoinResponse.java | 2 +- .../service/balance/vote/BalanceVoteService.java | 12 ++++++------ .../dto/VoteFinishedResponse.java | 2 +- .../balance/vote/BalanceVoteControllerTest.java | 6 +++--- .../balance/room/RoomDocumentationTest.java | 8 ++++---- .../vote/BalanceVoteDocumentationTest.java | 8 ++++---- .../service/balance/room/RoomServiceTest.java | 10 +++++----- .../balance/vote/BalanceVoteServiceTest.java | 16 ++++++++-------- 12 files changed, 40 insertions(+), 40 deletions(-) rename backend/src/main/java/ddangkong/service/{ => balance}/member/dto/MemberResponse.java (85%) rename backend/src/main/java/ddangkong/service/balance/{option => vote}/dto/VoteFinishedResponse.java (87%) diff --git a/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java b/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java index b323ca40..9c92a688 100644 --- a/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java +++ b/backend/src/main/java/ddangkong/controller/balance/vote/BalanceVoteController.java @@ -1,11 +1,11 @@ package ddangkong.controller.balance.vote; import ddangkong.aop.logging.Polling; +import ddangkong.service.balance.vote.BalanceVoteService; import ddangkong.service.balance.vote.dto.BalanceVoteRequest; import ddangkong.service.balance.vote.dto.BalanceVoteResponse; import ddangkong.service.balance.vote.dto.BalanceVoteResultResponse; -import ddangkong.service.balance.vote.BalanceVoteService; -import ddangkong.service.balance.option.dto.VoteFinishedResponse; +import ddangkong.service.balance.vote.dto.VoteFinishedResponse; import jakarta.validation.Valid; import jakarta.validation.constraints.Positive; import lombok.RequiredArgsConstructor; diff --git a/backend/src/main/java/ddangkong/service/member/dto/MemberResponse.java b/backend/src/main/java/ddangkong/service/balance/member/dto/MemberResponse.java similarity index 85% rename from backend/src/main/java/ddangkong/service/member/dto/MemberResponse.java rename to backend/src/main/java/ddangkong/service/balance/member/dto/MemberResponse.java index fa04c565..e040241b 100644 --- a/backend/src/main/java/ddangkong/service/member/dto/MemberResponse.java +++ b/backend/src/main/java/ddangkong/service/balance/member/dto/MemberResponse.java @@ -1,4 +1,4 @@ -package ddangkong.service.member.dto; +package ddangkong.service.balance.member.dto; import ddangkong.domain.member.Member; diff --git a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java index 454c822a..be6b1276 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/RoomService.java +++ b/backend/src/main/java/ddangkong/service/balance/room/RoomService.java @@ -1,9 +1,5 @@ package ddangkong.service.balance.room; -import ddangkong.service.member.dto.MemberResponse; -import ddangkong.service.balance.room.dto.RoomInfoResponse; -import ddangkong.service.balance.room.dto.RoomJoinResponse; -import ddangkong.service.balance.room.dto.RoomSettingRequest; import ddangkong.domain.balance.content.BalanceContent; import ddangkong.domain.balance.content.BalanceContentRepository; import ddangkong.domain.balance.content.Category; @@ -14,6 +10,10 @@ import ddangkong.domain.member.Member; import ddangkong.domain.member.MemberRepository; import ddangkong.exception.InternalServerException; +import ddangkong.service.balance.member.dto.MemberResponse; +import ddangkong.service.balance.room.dto.RoomInfoResponse; +import ddangkong.service.balance.room.dto.RoomJoinResponse; +import ddangkong.service.balance.room.dto.RoomSettingRequest; import ddangkong.service.balance.room.dto.RoundFinishedResponse; import java.time.Clock; import java.time.LocalDateTime; diff --git a/backend/src/main/java/ddangkong/service/balance/room/dto/RoomInfoResponse.java b/backend/src/main/java/ddangkong/service/balance/room/dto/RoomInfoResponse.java index fbc71a88..d9092071 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/dto/RoomInfoResponse.java +++ b/backend/src/main/java/ddangkong/service/balance/room/dto/RoomInfoResponse.java @@ -1,8 +1,8 @@ package ddangkong.service.balance.room.dto; -import ddangkong.service.member.dto.MemberResponse; import ddangkong.domain.balance.room.Room; import ddangkong.domain.member.Member; +import ddangkong.service.balance.member.dto.MemberResponse; import java.util.List; public record RoomInfoResponse( diff --git a/backend/src/main/java/ddangkong/service/balance/room/dto/RoomJoinResponse.java b/backend/src/main/java/ddangkong/service/balance/room/dto/RoomJoinResponse.java index 523c5263..1e294ead 100644 --- a/backend/src/main/java/ddangkong/service/balance/room/dto/RoomJoinResponse.java +++ b/backend/src/main/java/ddangkong/service/balance/room/dto/RoomJoinResponse.java @@ -1,6 +1,6 @@ package ddangkong.service.balance.room.dto; -import ddangkong.service.member.dto.MemberResponse; +import ddangkong.service.balance.member.dto.MemberResponse; public record RoomJoinResponse( Long roomId, diff --git a/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java b/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java index d4c33742..762e5633 100644 --- a/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java +++ b/backend/src/main/java/ddangkong/service/balance/vote/BalanceVoteService.java @@ -1,10 +1,5 @@ package ddangkong.service.balance.vote; -import ddangkong.service.balance.content.dto.BalanceContentGroupResponse; -import ddangkong.service.balance.content.dto.BalanceContentTotalResponse; -import ddangkong.service.balance.vote.dto.BalanceVoteRequest; -import ddangkong.service.balance.vote.dto.BalanceVoteResponse; -import ddangkong.service.balance.vote.dto.BalanceVoteResultResponse; import ddangkong.domain.balance.content.BalanceContent; import ddangkong.domain.balance.content.BalanceContentRepository; import ddangkong.domain.balance.option.BalanceOption; @@ -19,7 +14,12 @@ import ddangkong.domain.member.Member; import ddangkong.domain.member.MemberRepository; import ddangkong.exception.BadRequestException; -import ddangkong.service.balance.option.dto.VoteFinishedResponse; +import ddangkong.service.balance.content.dto.BalanceContentGroupResponse; +import ddangkong.service.balance.content.dto.BalanceContentTotalResponse; +import ddangkong.service.balance.vote.dto.BalanceVoteRequest; +import ddangkong.service.balance.vote.dto.BalanceVoteResponse; +import ddangkong.service.balance.vote.dto.BalanceVoteResultResponse; +import ddangkong.service.balance.vote.dto.VoteFinishedResponse; import java.time.Clock; import java.time.LocalDateTime; import java.util.List; diff --git a/backend/src/main/java/ddangkong/service/balance/option/dto/VoteFinishedResponse.java b/backend/src/main/java/ddangkong/service/balance/vote/dto/VoteFinishedResponse.java similarity index 87% rename from backend/src/main/java/ddangkong/service/balance/option/dto/VoteFinishedResponse.java rename to backend/src/main/java/ddangkong/service/balance/vote/dto/VoteFinishedResponse.java index abf1db94..13a3c31f 100644 --- a/backend/src/main/java/ddangkong/service/balance/option/dto/VoteFinishedResponse.java +++ b/backend/src/main/java/ddangkong/service/balance/vote/dto/VoteFinishedResponse.java @@ -1,4 +1,4 @@ -package ddangkong.service.balance.option.dto; +package ddangkong.service.balance.vote.dto; public record VoteFinishedResponse( boolean isFinished diff --git a/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java b/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java index 5256fe48..622f44fd 100644 --- a/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java +++ b/backend/src/test/java/ddangkong/controller/balance/vote/BalanceVoteControllerTest.java @@ -7,8 +7,6 @@ import static org.assertj.core.api.Assertions.assertThat; import ddangkong.controller.BaseControllerTest; -import ddangkong.service.balance.vote.dto.BalanceVoteRequest; -import ddangkong.service.balance.vote.dto.BalanceVoteResponse; import ddangkong.domain.balance.content.BalanceContent; import ddangkong.domain.balance.content.Category; import ddangkong.domain.balance.option.BalanceOption; @@ -16,7 +14,9 @@ import ddangkong.domain.balance.room.RoomContent; import ddangkong.domain.balance.vote.BalanceVote; import ddangkong.domain.member.Member; -import ddangkong.service.balance.option.dto.VoteFinishedResponse; +import ddangkong.service.balance.vote.dto.BalanceVoteRequest; +import ddangkong.service.balance.vote.dto.BalanceVoteResponse; +import ddangkong.service.balance.vote.dto.VoteFinishedResponse; import ddangkong.support.annotation.FixedClock; import io.restassured.RestAssured; import io.restassured.http.ContentType; diff --git a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java index 843602f6..a5cec153 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/room/RoomDocumentationTest.java @@ -22,16 +22,16 @@ import static org.springframework.restdocs.request.RequestDocumentation.queryParameters; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import ddangkong.service.member.dto.MemberResponse; import ddangkong.controller.balance.room.RoomController; +import ddangkong.documentation.BaseDocumentationTest; +import ddangkong.domain.balance.content.Category; +import ddangkong.service.balance.member.dto.MemberResponse; +import ddangkong.service.balance.room.RoomService; import ddangkong.service.balance.room.dto.RoomInfoResponse; import ddangkong.service.balance.room.dto.RoomJoinRequest; import ddangkong.service.balance.room.dto.RoomJoinResponse; import ddangkong.service.balance.room.dto.RoomSettingRequest; import ddangkong.service.balance.room.dto.RoomSettingResponse; -import ddangkong.documentation.BaseDocumentationTest; -import ddangkong.domain.balance.content.Category; -import ddangkong.service.balance.room.RoomService; import ddangkong.service.balance.room.dto.RoundFinishedResponse; import java.util.List; import org.junit.jupiter.api.Nested; diff --git a/backend/src/test/java/ddangkong/documentation/balance/vote/BalanceVoteDocumentationTest.java b/backend/src/test/java/ddangkong/documentation/balance/vote/BalanceVoteDocumentationTest.java index cf8447f5..5358244f 100644 --- a/backend/src/test/java/ddangkong/documentation/balance/vote/BalanceVoteDocumentationTest.java +++ b/backend/src/test/java/ddangkong/documentation/balance/vote/BalanceVoteDocumentationTest.java @@ -17,17 +17,17 @@ import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import ddangkong.controller.balance.vote.BalanceVoteController; +import ddangkong.documentation.BaseDocumentationTest; import ddangkong.service.balance.content.dto.BalanceContentGroupResponse; import ddangkong.service.balance.content.dto.BalanceContentTotalResponse; import ddangkong.service.balance.option.dto.BalanceOptionGroupResponse; import ddangkong.service.balance.option.dto.BalanceOptionTotalResponse; -import ddangkong.controller.balance.vote.BalanceVoteController; +import ddangkong.service.balance.vote.BalanceVoteService; import ddangkong.service.balance.vote.dto.BalanceVoteRequest; import ddangkong.service.balance.vote.dto.BalanceVoteResponse; import ddangkong.service.balance.vote.dto.BalanceVoteResultResponse; -import ddangkong.documentation.BaseDocumentationTest; -import ddangkong.service.balance.vote.BalanceVoteService; -import ddangkong.service.balance.option.dto.VoteFinishedResponse; +import ddangkong.service.balance.vote.dto.VoteFinishedResponse; import java.util.List; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; diff --git a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java index 01cf6dc3..82e022a4 100644 --- a/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/room/RoomServiceTest.java @@ -4,11 +4,6 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertAll; -import ddangkong.service.member.dto.MemberResponse; -import ddangkong.service.balance.room.dto.RoomInfoResponse; -import ddangkong.service.balance.room.dto.RoomJoinResponse; -import ddangkong.service.balance.room.dto.RoomSettingRequest; -import ddangkong.service.balance.room.dto.RoomSettingResponse; import ddangkong.domain.balance.content.BalanceContent; import ddangkong.domain.balance.content.BalanceContentRepository; import ddangkong.domain.balance.content.Category; @@ -19,6 +14,11 @@ import ddangkong.domain.balance.room.RoomStatus; import ddangkong.exception.BadRequestException; import ddangkong.service.BaseServiceTest; +import ddangkong.service.balance.member.dto.MemberResponse; +import ddangkong.service.balance.room.dto.RoomInfoResponse; +import ddangkong.service.balance.room.dto.RoomJoinResponse; +import ddangkong.service.balance.room.dto.RoomSettingRequest; +import ddangkong.service.balance.room.dto.RoomSettingResponse; import ddangkong.service.balance.room.dto.RoundFinishedResponse; import java.util.List; import org.assertj.core.api.Assertions; diff --git a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java index ba93ca03..6ac86c47 100644 --- a/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java +++ b/backend/src/test/java/ddangkong/service/balance/vote/BalanceVoteServiceTest.java @@ -7,13 +7,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import ddangkong.service.balance.content.dto.BalanceContentGroupResponse; -import ddangkong.service.balance.content.dto.BalanceContentTotalResponse; -import ddangkong.service.balance.option.dto.BalanceOptionGroupResponse; -import ddangkong.service.balance.option.dto.BalanceOptionTotalResponse; -import ddangkong.service.balance.vote.dto.BalanceVoteRequest; -import ddangkong.service.balance.vote.dto.BalanceVoteResponse; -import ddangkong.service.balance.vote.dto.BalanceVoteResultResponse; import ddangkong.domain.balance.content.BalanceContent; import ddangkong.domain.balance.content.Category; import ddangkong.domain.balance.option.BalanceOption; @@ -23,7 +16,14 @@ import ddangkong.domain.member.Member; import ddangkong.exception.BadRequestException; import ddangkong.service.BaseServiceTest; -import ddangkong.service.balance.option.dto.VoteFinishedResponse; +import ddangkong.service.balance.content.dto.BalanceContentGroupResponse; +import ddangkong.service.balance.content.dto.BalanceContentTotalResponse; +import ddangkong.service.balance.option.dto.BalanceOptionGroupResponse; +import ddangkong.service.balance.option.dto.BalanceOptionTotalResponse; +import ddangkong.service.balance.vote.dto.BalanceVoteRequest; +import ddangkong.service.balance.vote.dto.BalanceVoteResponse; +import ddangkong.service.balance.vote.dto.BalanceVoteResultResponse; +import ddangkong.service.balance.vote.dto.VoteFinishedResponse; import ddangkong.support.annotation.FixedClock; import java.time.LocalDateTime; import java.util.List; From 40e1776d668da06f2077c737555be8c24827c55a Mon Sep 17 00:00:00 2001 From: rbgksqkr Date: Thu, 15 Aug 2024 14:17:09 +0900 Subject: [PATCH 0691/1013] =?UTF-8?q?design:=20pretandard=20=EC=9B=B9?= =?UTF-8?q?=ED=8F=B0=ED=8A=B8=20=EC=84=A4=EC=A0=95=20#149?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/index.html | 2 ++ frontend/src/styles/GlobalStyle.ts | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/frontend/index.html b/frontend/index.html index 1024288a..bf2da022 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -4,6 +4,8 @@ ddangkong +