diff --git a/.gitignore b/.gitignore index fd3dbb5..a84107a 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ yarn-debug.log* yarn-error.log* # local env files +.env .env*.local # vercel diff --git a/next.config.mjs b/next.config.mjs index 4678774..d69ac54 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,4 +1,17 @@ /** @type {import('next').NextConfig} */ -const nextConfig = {}; +const nextConfig = { + webpack5: true, + + reactStrictMode: true, + webpack: (config) => { + config.module.rules.push({ + test: /\.svg$/, + use: ["@svgr/webpack"], + }); + config.cache = false; + + return config; + }, +}; export default nextConfig; diff --git a/package-lock.json b/package-lock.json index 9eef959..b2a8150 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,9 +10,11 @@ "dependencies": { "next": "14.2.3", "react": "^18", - "react-dom": "^18" + "react-dom": "^18", + "zustand": "^4.5.2" }, "devDependencies": { + "@svgr/webpack": "^8.1.0", "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", @@ -21,6 +23,1950 @@ "typescript": "^5" } }, + "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, + "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, + "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/core/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/@babel/core/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/@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-compilation-targets/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/@babel/helper-compilation-targets/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/@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-class-features-plugin/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/@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-create-regexp-features-plugin/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/@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, + "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/highlight/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/@babel/highlight/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/@babel/highlight/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/@babel/highlight/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/@babel/highlight/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/@babel/highlight/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/@babel/highlight/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/@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-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", + "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-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", + "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-classes/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/@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-react-constant-elements": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.24.7.tgz", + "integrity": "sha512-7LidzZfUXyfZ8/buRW6qIIHBY8wAZ1OrY9c/wTr8YhZ6vMPo+Uc/CVFLYY1spZrEQlD4w5u8wjqk5NQ3OVqQKA==", + "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-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", + "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-typescript": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.7.tgz", + "integrity": "sha512-iLD3UNkgx2n/HrjBesVbYX6j0yqn/sJktvbtKKgcaLIQ4bTTQ8obAypc1VpyHPD2y4Phh9zHOaAt8e/L14wCpw==", + "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-typescript": "^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-env/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/@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/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", + "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", @@ -33,6 +1979,64 @@ "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/traverse/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/@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/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -166,6 +2170,54 @@ "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/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "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/@next/env": { "version": "14.2.3", "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.3.tgz", @@ -270,102 +2322,359 @@ "node": ">= 10" } }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.3.tgz", - "integrity": "sha512-AEHIw/dhAMLNFJFJIJIyOFDzrzI5bAjI9J26gbO5xhAKHYTZ9Or04BesFPXiAYXDNdrwTP2dQceYA4dL1geu8A==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.3.tgz", + "integrity": "sha512-AEHIw/dhAMLNFJFJIJIyOFDzrzI5bAjI9J26gbO5xhAKHYTZ9Or04BesFPXiAYXDNdrwTP2dQceYA4dL1geu8A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.3.tgz", + "integrity": "sha512-vga40n1q6aYb0CLrM+eEmisfKCR45ixQYXuBXxOOmmoV8sYST9k7E3US32FsY+CkkF7NtzdcebiFT4CHuMSyZw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.3.tgz", + "integrity": "sha512-Q1/zm43RWynxrO7lW4ehciQVj+5ePBhOK+/K2P7pLFX3JaJ/IZVC69SHidrmZSOkqz7ECIOhhy7XhAFG4JYyHA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "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", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.3.tgz", + "integrity": "sha512-qC/xYId4NMebE6w/V33Fh9gWxLgURiNYgVNObbJl2LZv0GUUItCcCqC5axQSwRaAgaxl2mELq1rMzlswaQ0Zxg==", + "dev": true + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", + "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", + "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", + "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", + "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", + "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", + "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", + "dev": true, "engines": { - "node": ">= 10" + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.3.tgz", - "integrity": "sha512-vga40n1q6aYb0CLrM+eEmisfKCR45ixQYXuBXxOOmmoV8sYST9k7E3US32FsY+CkkF7NtzdcebiFT4CHuMSyZw==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], + "node_modules/@svgr/babel-preset": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", + "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", + "dev": true, + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", + "@svgr/babel-plugin-transform-svg-component": "8.0.0" + }, "engines": { - "node": ">= 10" + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.3.tgz", - "integrity": "sha512-Q1/zm43RWynxrO7lW4ehciQVj+5ePBhOK+/K2P7pLFX3JaJ/IZVC69SHidrmZSOkqz7ECIOhhy7XhAFG4JYyHA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], + "node_modules/@svgr/core": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", + "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^8.1.3", + "snake-case": "^3.0.4" + }, "engines": { - "node": ">= 10" + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" } }, - "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/@svgr/hast-util-to-babel-ast": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", + "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", "dev": true, "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "@babel/types": "^7.21.3", + "entities": "^4.4.0" }, "engines": { - "node": ">= 8" + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" } }, - "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/@svgr/plugin-jsx": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", + "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", "dev": true, + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "@svgr/hast-util-to-babel-ast": "8.0.0", + "svg-parser": "^2.0.4" + }, "engines": { - "node": ">= 8" + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" } }, - "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/@svgr/plugin-svgo": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", + "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", "dev": true, "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "cosmiconfig": "^8.1.3", + "deepmerge": "^4.3.1", + "svgo": "^3.0.2" }, "engines": { - "node": ">= 8" + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" } }, - "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/@svgr/webpack": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", + "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", "dev": true, - "optional": true, + "dependencies": { + "@babel/core": "^7.21.3", + "@babel/plugin-transform-react-constant-elements": "^7.21.3", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.21.0", + "@svgr/core": "8.1.0", + "@svgr/plugin-jsx": "8.1.0", + "@svgr/plugin-svgo": "8.1.0" + }, "engines": { "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" } }, - "node_modules/@rushstack/eslint-patch": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.3.tgz", - "integrity": "sha512-qC/xYId4NMebE6w/V33Fh9gWxLgURiNYgVNObbJl2LZv0GUUItCcCqC5axQSwRaAgaxl2mELq1rMzlswaQ0Zxg==", - "dev": true - }, "node_modules/@swc/counter": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", @@ -380,6 +2689,15 @@ "tslib": "^2.4.0" } }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -399,13 +2717,13 @@ "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 + "devOptional": 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, + "devOptional": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -839,12 +3157,66 @@ "dequal": "^2.0.3" } }, + "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-corejs2/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/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/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": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -867,6 +3239,38 @@ "node": ">=8" } }, + "node_modules/browserslist": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "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.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -906,6 +3310,18 @@ "node": ">=6" } }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001629", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001629.tgz", @@ -964,31 +3380,159 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, "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/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/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/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/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/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": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "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", + "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/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", "dev": true, "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "css-tree": "~2.2.0" }, "engines": { - "node": ">= 8" + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" } }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "dev": true + }, "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 + "devOptional": true }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -1070,6 +3614,15 @@ "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", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -1137,12 +3690,83 @@ "node": ">=6.0.0" } }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?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": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dev": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "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/electron-to-chromium": { + "version": "1.4.792", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.792.tgz", + "integrity": "sha512-rkg5/N3L+Y844JyfgPUyuKK0Hk0efo3JNxUDKvz3HgP6EmN4rNGhr2D8boLsfTV/hGo7ZGAL8djw+jlg99zQyA==", + "dev": true + }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -1162,6 +3786,27 @@ "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/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==", + "dev": true, + "dependencies": { + "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", @@ -1320,6 +3965,15 @@ "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-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -1926,6 +4580,15 @@ "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, + "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", @@ -2268,6 +4931,12 @@ "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==", + "dev": true + }, "node_modules/is-async-function": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", @@ -2667,12 +5336,30 @@ "js-yaml": "bin/js-yaml.js" } }, + "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-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", + "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", @@ -2752,6 +5439,12 @@ "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", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -2767,6 +5460,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -2784,6 +5483,15 @@ "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": "10.2.2", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", @@ -2793,6 +5501,12 @@ "node": "14 || >=16.14" } }, + "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/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -2923,6 +5637,34 @@ } } }, + "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-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/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-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -3116,6 +5858,24 @@ "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==", + "dev": true, + "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/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -3326,12 +6086,39 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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/regexp.prototype.flags": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", @@ -3350,6 +6137,44 @@ "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", + "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/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -3602,6 +6427,16 @@ "node": ">=8" } }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/source-map-js": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", @@ -3850,6 +6685,37 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", + "dev": true + }, + "node_modules/svgo": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", + "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", + "dev": true, + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -3865,6 +6731,15 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "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", @@ -4037,6 +6912,76 @@ "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/update-browserslist-db": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "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", @@ -4046,6 +6991,14 @@ "punycode": "^2.1.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4249,6 +7202,12 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": 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": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -4260,6 +7219,33 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zustand": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.2.tgz", + "integrity": "sha512-2cN1tPkDVkwCy5ickKrI7vijSjPksFRfqS6237NzT0vqSsztTNnQdHw9mmN7uBdk3gceVXU0a+21jFzFzAc9+g==", + "dependencies": { + "use-sync-external-store": "1.2.0" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } } } } diff --git a/package.json b/package.json index ee4e927..8edb6ba 100644 --- a/package.json +++ b/package.json @@ -9,16 +9,18 @@ "lint": "next lint" }, "dependencies": { + "next": "14.2.3", "react": "^18", "react-dom": "^18", - "next": "14.2.3" + "zustand": "^4.5.2" }, "devDependencies": { - "typescript": "^5", + "@svgr/webpack": "^8.1.0", "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", "eslint": "^8", - "eslint-config-next": "14.2.3" + "eslint-config-next": "14.2.3", + "typescript": "^5" } } diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..d04448e Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/favicon.png b/public/favicon.png new file mode 100644 index 0000000..afd262a Binary files /dev/null and b/public/favicon.png differ diff --git a/public/fonts/Pretendard-Bold.ttf b/public/fonts/Pretendard-Bold.ttf new file mode 100644 index 0000000..fb07fc6 Binary files /dev/null and b/public/fonts/Pretendard-Bold.ttf differ diff --git a/public/fonts/Pretendard-Medium.ttf b/public/fonts/Pretendard-Medium.ttf new file mode 100644 index 0000000..1db67c6 Binary files /dev/null and b/public/fonts/Pretendard-Medium.ttf differ diff --git a/public/fonts/Pretendard-Regular.ttf b/public/fonts/Pretendard-Regular.ttf new file mode 100644 index 0000000..01147e9 Binary files /dev/null and b/public/fonts/Pretendard-Regular.ttf differ diff --git a/public/icons/Background.svg b/public/icons/Background.svg new file mode 100644 index 0000000..904f1e1 --- /dev/null +++ b/public/icons/Background.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/public/icons/Check.svg b/public/icons/Check.svg new file mode 100644 index 0000000..4b11135 --- /dev/null +++ b/public/icons/Check.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/icons/Community.svg b/public/icons/Community.svg new file mode 100644 index 0000000..f632235 --- /dev/null +++ b/public/icons/Community.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/Down.svg b/public/icons/Down.svg new file mode 100644 index 0000000..89f2579 --- /dev/null +++ b/public/icons/Down.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/Email.svg b/public/icons/Email.svg new file mode 100644 index 0000000..67211e3 --- /dev/null +++ b/public/icons/Email.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/public/icons/Filter.svg b/public/icons/Filter.svg new file mode 100644 index 0000000..3cb57e0 --- /dev/null +++ b/public/icons/Filter.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/icons/Hamburger.svg b/public/icons/Hamburger.svg new file mode 100644 index 0000000..0b2e496 --- /dev/null +++ b/public/icons/Hamburger.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/Help.svg b/public/icons/Help.svg new file mode 100644 index 0000000..1093372 --- /dev/null +++ b/public/icons/Help.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/LeftArrow.svg b/public/icons/LeftArrow.svg new file mode 100644 index 0000000..659cee7 --- /dev/null +++ b/public/icons/LeftArrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/Logo1.svg b/public/icons/Logo1.svg new file mode 100644 index 0000000..f0a330b --- /dev/null +++ b/public/icons/Logo1.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/public/icons/Logo2.svg b/public/icons/Logo2.svg new file mode 100644 index 0000000..4aab379 --- /dev/null +++ b/public/icons/Logo2.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/public/icons/LogoBig.png b/public/icons/LogoBig.png new file mode 100644 index 0000000..94d281b Binary files /dev/null and b/public/icons/LogoBig.png differ diff --git a/public/icons/LogoRow.svg b/public/icons/LogoRow.svg new file mode 100644 index 0000000..e26123b --- /dev/null +++ b/public/icons/LogoRow.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/public/icons/Message.svg b/public/icons/Message.svg new file mode 100644 index 0000000..12a9965 --- /dev/null +++ b/public/icons/Message.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/Moon.svg b/public/icons/Moon.svg new file mode 100644 index 0000000..b131bd2 --- /dev/null +++ b/public/icons/Moon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/icons/MyProfile.svg b/public/icons/MyProfile.svg new file mode 100644 index 0000000..a780546 --- /dev/null +++ b/public/icons/MyProfile.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/public/icons/Mypage.svg b/public/icons/Mypage.svg new file mode 100644 index 0000000..a9bbbcd --- /dev/null +++ b/public/icons/Mypage.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/Notice.svg b/public/icons/Notice.svg new file mode 100644 index 0000000..3da99cd --- /dev/null +++ b/public/icons/Notice.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/Password.svg b/public/icons/Password.svg new file mode 100644 index 0000000..4ea8643 --- /dev/null +++ b/public/icons/Password.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/public/icons/Play.svg b/public/icons/Play.svg new file mode 100644 index 0000000..72abec6 --- /dev/null +++ b/public/icons/Play.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/icons/SSH.svg b/public/icons/SSH.svg new file mode 100644 index 0000000..a021ad9 --- /dev/null +++ b/public/icons/SSH.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/public/icons/Search.svg b/public/icons/Search.svg new file mode 100644 index 0000000..eb14a4d --- /dev/null +++ b/public/icons/Search.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/Space.svg b/public/icons/Space.svg new file mode 100644 index 0000000..1f992ab --- /dev/null +++ b/public/icons/Space.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/Sun.svg b/public/icons/Sun.svg new file mode 100644 index 0000000..f948db0 --- /dev/null +++ b/public/icons/Sun.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/icons/Up.svg b/public/icons/Up.svg new file mode 100644 index 0000000..825ac39 --- /dev/null +++ b/public/icons/Up.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/Username.svg b/public/icons/Username.svg new file mode 100644 index 0000000..58c629f --- /dev/null +++ b/public/icons/Username.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/icons/VSCode.svg b/public/icons/VSCode.svg new file mode 100644 index 0000000..cfa683a --- /dev/null +++ b/public/icons/VSCode.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/next.svg b/public/next.svg deleted file mode 100644 index 5174b28..0000000 --- a/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/vercel.svg b/public/vercel.svg deleted file mode 100644 index d2f8422..0000000 --- a/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/app/(main)/container/[id]/page.module.css b/src/app/(main)/container/[id]/page.module.css new file mode 100644 index 0000000..ef82c46 --- /dev/null +++ b/src/app/(main)/container/[id]/page.module.css @@ -0,0 +1,88 @@ +.container { + display: relative; + z-index: 3; + padding-bottom: 100px; +} + +.headerTitle { + font-size: 24px; + font-family: "Pretendard-bold"; + padding: 10px 0; +} + +.searchContainer { + margin-top: 20px; +} + +.header { + display: flex; + align-items: center; + justify-content: space-between; +} + +.searchBox { + position: relative; + width: 100%; + max-width: 400px; + min-width: 300px; +} + +.searchInput { + width: 100%; + padding: 15px 40px 15px 20px; + font-size: 16px; + border-radius: 10px; +} + +.searchIcon { + position: absolute; + right: 15px; + top: 50%; + transform: translateY(-50%); + fill: var(--gray-color); +} + +.searchInput:focus-visible { + border-color: var(--orange-color); + outline: var(--orange-color); + outline-width: 5px; +} + +.searchInput:focus + .searchIcon { + fill: var(--orange-color); +} + +.results { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 30px; + margin-top: 50px; + padding-bottom: 20px; +} +@media (max-width: 1000px) { + .header { + flex-direction: column; + align-items: flex-start; + gap: 10px; + } +} + +@media (max-width: 768px) { + .searchBox { + width: 300px; + } + + .filter { + display: none; + } + + .result { + display: flex; + flex-direction: column; + gap: 20px; + } + + .resultItem { + flex: 1 1 100%; + } +} diff --git a/src/app/(main)/container/[id]/page.tsx b/src/app/(main)/container/[id]/page.tsx new file mode 100644 index 0000000..b0ad280 --- /dev/null +++ b/src/app/(main)/container/[id]/page.tsx @@ -0,0 +1,90 @@ +"use client"; + +import { useParams } from "next/navigation"; +import { useState, useEffect } from "react"; +import SearchIcon from "/public/icons/Search.svg"; +import styles from "./page.module.css"; +import Filter from "@/components/container/Filter"; +import Container from "@/components/container/Container"; +import dummyData from "@/data/dummy_container_data.json"; + +export default function Home() { + const { id: container } = useParams(); + + const [searchQuery, setSearchQuery] = useState(""); + const [filteredContainers, setFilteredContainers] = useState(dummyData); + const [filterOption, setFilterOption] = useState(""); + + const [modalOpen, setModalOpen] = useState(false); + + const titles = { + recent: "최근 실행 컨테이너", + semester: "이번 학기 컨테이너", + all: "전체 학기 컨테이너", + }; + + const title = + titles[container as keyof typeof titles] || "전체 학기 컨테이너"; + + useEffect(() => { + let filtered = dummyData; + + if (searchQuery !== "") { + filtered = filtered.filter( + (c) => + c.course_name.toLowerCase().includes(searchQuery.toLowerCase()) || + c.professor_name.toLowerCase().includes(searchQuery.toLowerCase()) + ); + } + + if (container === "recent" || filterOption === "recent") { + filtered = filtered.filter((c) => + ["Fall 2023", "Spring 2024"].includes(c.semester) + ); + } else if (container === "semester" || filterOption === "semester") { + filtered = filtered.filter((c) => c.semester === "Spring 2024"); + } + + setFilteredContainers(filtered); + }, [searchQuery, filterOption, container]); + + const handleSearch = (event: React.ChangeEvent) => { + setSearchQuery(event.target.value); + }; + + const handleFilterSelect = (option: string) => { + setFilterOption(option); + }; + + const handleModalOpen = () => { + setModalOpen(true); + }; + + return ( +
+
{title}
+
+
+
+ + +
+
+ +
+
+
+
+ {filteredContainers.map((container, index) => ( + + ))} +
+
+ ); +} diff --git a/src/app/(main)/help/page.module.css b/src/app/(main)/help/page.module.css new file mode 100644 index 0000000..471d710 --- /dev/null +++ b/src/app/(main)/help/page.module.css @@ -0,0 +1,150 @@ +.container { + padding-bottom: 100px; +} +.headerTitle { + font-size: 24px; + font-family: "Pretendard-bold"; + padding: 10px 0; +} + +.header { + display: flex; + /* // 중앙정렬 */ + justify-content: space-between; + align-items: center; + padding-top: 12px; +} + +.searchBox { + position: relative; + width: 100%; + max-width: 400px; + min-width: 300px; +} +.viewSelector { + margin-top: 10px; +} + +.searchInput { + width: 100%; + padding: 15px 40px 15px 20px; + font-size: 16px; + border-radius: 10px; +} + +.searchIcon { + position: absolute; + right: 15px; + top: 50%; + transform: translateY(-50%); + fill: var(--gray-color); +} + +.searchInput:focus-visible { + border-color: var(--orange-color); + outline: var(--orange-color); + outline-width: 5px; +} + +.searchInput:focus + .searchIcon { + fill: var(--orange-color); +} + +.viewSelector { + display: flex; + justify-content: center; + align-items: center; +} + +.helpItems { + display: flex; + gap: 20px; +} + +.grid { + display: grid; + gap: 20px; + grid-template-columns: repeat(auto-fill, 300px); +} + +.column { + flex-direction: column; +} + +.category { + padding-bottom: 20px; +} + +.categoryTitle { + font-size: 24px; + margin: 20px 0; +} + +.categoryList { + position: fixed; + top: 280px; + right: 20px; + display: flex; + flex-direction: column; + gap: 10px; + background-color: var(--orange-color); + padding: 10px; + border-radius: 20px; + z-index: 1; +} + +.categoryButton { + background-color: transparent; + padding: 10px; + border: none; + border-radius: 8px; + cursor: pointer; + text-align: left; + color: var(--white-color); +} + +.categoryButton:hover { + color: var(--gray-color); +} + +.mainContent { + flex-grow: 1; +} + +.bodyContent { + padding-top: 20px; + padding-right: 100px; +} + +@media (max-width: 1024px) { + .searchBox { + width: 320px; + } + .viewSelector { + display: none; + } +} + +@media (max-width: 768px) { + .viewSelector { + display: none; + } + .categoryList { + display: none; + } + + .helpItems { + flex-direction: column !important; + width: 100%; + } + + .grid { + display: flex; + flex-direction: column; + width: 100%; + } + + .column { + width: 320px; + } +} diff --git a/src/app/(main)/help/page.tsx b/src/app/(main)/help/page.tsx new file mode 100644 index 0000000..d49c2a1 --- /dev/null +++ b/src/app/(main)/help/page.tsx @@ -0,0 +1,125 @@ +"use client"; + +import React, { useState, ChangeEvent, useEffect } from "react"; +import styles from "./page.module.css"; +import dummyHelpData from "@/data/dummy_help_data.json"; +import HelpItem from "@/components/help/HelpItem"; +import Filter from "@/components/help/HelpFilter"; +import SearchIcon from "/public/icons/Search.svg"; + +interface HelpData { + id: number; + title: string; + body: string; + category: string; +} + +const Help = () => { + const [searchQuery, setSearchQuery] = useState(""); + const [view, setView] = useState("column"); + const [isWide, setIsWide] = useState(false); // 브라우저의 너비 상태 + + const handleSearchChange = (event: ChangeEvent) => { + setSearchQuery(event.target.value); + }; + + const handleViewChange = (view: string) => { + setView(view); + }; + + const handleCategoryClick = (category: string) => { + if (typeof window !== "undefined") { + document.getElementById(category)?.scrollIntoView({ behavior: "smooth" }); + } + }; + + useEffect(() => { + const handleResize = () => { + if (typeof window !== "undefined") { + setIsWide(window.innerWidth > 768); + setView(window.innerWidth <= 768 ? "column" : "grid"); + } + }; + + handleResize(); + window.addEventListener("resize", handleResize); + + return () => { + window.removeEventListener("resize", handleResize); + }; + }, []); + + const filteredHelpData = dummyHelpData.filter((item) => + item.title.toLowerCase().includes(searchQuery.toLowerCase()) + ); + + const categorizedHelpData = filteredHelpData.reduce( + (acc: { [key: string]: HelpData[] }, item) => { + if (!acc[item.category]) { + acc[item.category] = []; + } + acc[item.category].push(item); + return acc; + }, + {} + ); + + return ( +
+
도움말
+
+
+
+ + +
+
+ +
+
+
+ {Object.keys(categorizedHelpData).map((category) => ( +
+

{category}

+
+ {categorizedHelpData[category].map((item) => ( + + ))} +
+
+ ))} +
+
+
+ {Object.keys(categorizedHelpData).map((category) => ( + + ))} +
+
+ ); +}; + +export default Help; diff --git a/src/app/(main)/layout.module.css b/src/app/(main)/layout.module.css new file mode 100644 index 0000000..f8dcad4 --- /dev/null +++ b/src/app/(main)/layout.module.css @@ -0,0 +1,149 @@ +.layout { + display: flex; + min-height: 100dvh; + height: 100%; + background-color: var(--gray-color); +} + +.sidebar { + width: 310px; + min-width: 310px; + padding: 20px; + transition: transform 0.3s ease, opacity 0.3s ease; + transform: translateX(0); + height: 100%; + background-color: var(--gray-color); +} + +.sidebar.closed { + transform: translateX(-100%); + opacity: 0; +} + +.logo { + display: flex; + align-items: center; + justify-content: space-between; +} + +.school { + font-size: 24px; + font-family: "Pretendard-bold"; + height: 80px; + display: flex; + align-items: center; +} + +.userContainer { + display: flex; + align-items: center; + padding-bottom: 20px; + gap: 10px; + border-bottom: 1px dashed var(--lightgray-color); +} + +.userInfo { + display: flex; + padding-bottom: 5px; + gap: 5px; + font-family: "Pretendard-bold"; + font-size: 20px; +} + +.studentsId { + font-family: "Pretendard-Regular"; + font-size: 16px; +} + +.studentId { + font-family: "Pretendard-Regular"; + font-size: 18px; +} + +.menu { + padding: 50px 0 20px 0; + display: flex; + flex-direction: column; + gap: 30px; +} + +.menuItem { + display: flex; + align-items: center; + gap: 15px; + height: 60px; + padding: 10px; + border-radius: 10px; + font-family: "Pretendard-bold"; + transition: color 0.3s ease, background-color 0.3s ease; +} + +.menuText { + font-size: 20px; + font-family: "Pretendard-bold"; +} + +.subMenu { + padding-left: 20px; + margin-top: -20px; +} + +.subMenu div { + font-family: "Pretendard-Medium"; + font-size: 18px; +} + +.down { + margin-left: auto; +} + +.menu a { + display: block; + color: var(--white-color); + text-decoration: none; + font-size: 20px; + font-family: "Pretendard-bold"; +} + +.menuItem:hover { + color: var(--orange-color); +} + +.menuItem.active { + background-color: var(--orange50-color); +} + +.content { + flex-grow: 1; + background-color: var(--black-color); + padding: 40px 40px 0; + transition: margin-left 0.3s ease; + min-width: 500px; +} + +.left { + background-color: var(--black-color); + width: 100%; + height: 100dvh; + transition: 0.15s ease; +} + +.topName { + display: flex; + flex-direction: row; + align-items: center; + padding: 50px 40px 0; + font-size: 24px; + font-family: "Pretendard-Medium"; + gap: 10px; + background-color: var(--black-color); +} + +.left.shifted { + margin-left: -310px; + background-color: var(--black-color); +} + +.iconButton { + cursor: pointer; +} diff --git a/src/app/(main)/layout.tsx b/src/app/(main)/layout.tsx new file mode 100644 index 0000000..28a2670 --- /dev/null +++ b/src/app/(main)/layout.tsx @@ -0,0 +1,199 @@ +"use client"; + +import { ReactNode, useEffect, useState } from "react"; +import styles from "./layout.module.css"; +import { useAuthStore } from "@/store/authStore"; +import Link from "next/link"; +import { redirect, usePathname } from "next/navigation"; +import Image from "next/image"; +import LeftArrowIcon from "/public/icons/LeftArrow.svg"; +import HamburgerIcon from "/public/icons/Hamburger.svg"; + +interface LayoutProps { + children: ReactNode; +} + +export default function Layout({ children }: LayoutProps) { + const user = useAuthStore((state) => state.user); + const isLoggedIn = useAuthStore((state) => state.isLoggedIn); + const isLoading = useAuthStore((state) => state.isLoading); + const [isSidebarOpen, setSidebarOpen] = useState(true); + + useEffect(() => { + if (!isLoggedIn && !isLoading) { + redirect("/onboarding"); + } + }, [isLoggedIn, isLoading]); + + const navigation = usePathname(); + + const isActive = (path: string) => { + return navigation === path ? styles.active : ""; + }; + + const toggleSidebar = () => { + setSidebarOpen(!isSidebarOpen); + }; + + const handleResize = () => { + if (window.innerWidth <= 768) { + setSidebarOpen(false); + } else { + setSidebarOpen(true); + } + }; + + useEffect(() => { + handleResize(); // 초기 실행 시 한 번 호출 + window.addEventListener("resize", handleResize); + return () => { + window.removeEventListener("resize", handleResize); + }; + }, []); + + return ( +
+ {/* 사이드바 */} +
+
+
성균관대학교
+ +
+ +
+ myprofile +
+
+
{user?.name}
+
{user?.isStudent ? "- 학생" : " - 교수"}
+
+
{user?.studentId}
+
+
+
+
+ container +
스페이스
+ container +
+
+ +
+
전체 학기 컨테이너
+
+ + +
+
최근 실행 컨테이너
+
+ + +
+
이번 학기 컨테이너
+
+ +
+ +
+ notice +
공지
+
+ + +
+ community +
메세지
+
+ + +
+ help +
도움말
+
+ + +
+ mypage +
마이페이지
+
+ +
+
+ + {/* 메인 컨텐츠 */} +
+
+ {!isSidebarOpen && ( + + )} +
{user?.name}
+
/ {user?.studentId}
+
+
+ {children} +
+
+
+ ); +} diff --git a/src/app/(main)/message/page.module.css b/src/app/(main)/message/page.module.css new file mode 100644 index 0000000..3b92f42 --- /dev/null +++ b/src/app/(main)/message/page.module.css @@ -0,0 +1,136 @@ +.messagePageLightMode { + --theme-color: var(--white-color); + --theme-color2: var(--white-color); + --theme-color3: var(--white-color); +} + +.messagePageDarkMode { + --theme-color: var(--gray-color); + --theme-color2: var(--lightgray-color); + --theme-color3: var(--lightgray2-color); +} + +.container { + border-radius: 8px; + padding-bottom: 100px; +} + +.header { + margin-bottom: 20px; + display: flex; + justify-content: space-between; +} + +.headerTitle { + font-size: 24px; + font-family: "Pretendard-bold"; + padding: 10px 0; +} +.selection { + display: flex; + gap: 20px; + margin: 20px 0; +} + +.selectBox { + flex: 1; +} + +.select { + width: 100%; + padding: 10px; + border-radius: 8px; + background-color: var(--theme-color2); +} + +.professorName { + display: flex; + align-items: center; + font-size: 16px; +} + +.messages { + max-height: 700px; + overflow-y: auto; + margin-bottom: 20px; + padding: 10px; + border-radius: 8px; + background-color: var(--theme-color); +} + +.message { + margin-bottom: 10px; + max-width: 70%; +} + +.message.sent { + align-self: flex-end; + background-color: var(--orange50-color); + color: var(--white-color); + border-radius: 8px 8px 0 8px; + padding: 10px; + margin-left: auto; +} + +.message.received { + align-self: flex-start; + background-color: var(--lightgray2-color); + border-radius: 8px 8px 8px 0; + padding: 10px; + margin-right: auto; +} + +.messageHeader { + display: flex; + justify-content: space-between; + font-size: 12px; + color: var(--lightgray-color); +} + +.sender { + font-weight: bold; +} + +.text { + padding: 5px 0; + font-size: 14px; + color: var(--black-color); +} + +.inputForm { + display: flex; + gap: 10px; +} + +.input { + flex: 1; + padding: 10px; + border-radius: 8px; + background-color: var(--theme-color3); +} + +.input:focus-visible { + border-color: var(--orange-color); + outline: var(--orange-color); + outline-width: 5px; +} + +.sendButton { + padding: 10px 20px; + border: none; + border-radius: 8px; + background-color: var(--orange-color); + color: var(--white-color); + cursor: pointer; + transition: background-color 0.3s ease; +} + +.sendButton:hover { + background-color: var(--orange-color); +} + +@media (max-width: 430px) { + .container { + width: 320px; + } +} diff --git a/src/app/(main)/message/page.tsx b/src/app/(main)/message/page.tsx new file mode 100644 index 0000000..e55c0f8 --- /dev/null +++ b/src/app/(main)/message/page.tsx @@ -0,0 +1,150 @@ +// components/MessagePage.tsx +"use client"; + +import React, { useState, ChangeEvent, FormEvent, useEffect } from "react"; +import styles from "./page.module.css"; +import dummyData from "@/data/dummy_notice_data.json"; +import dummyMessageData from "@/data/dummy_message_data.json"; +import ToggleButton from "@/components/common/ToggleButton"; + +interface Message { + id: number; + sender: string; + text: string; + timestamp: string; +} + +const MessagePage = () => { + const [selectedCourse, setSelectedCourse] = useState(""); + const [selectedProfessor, setSelectedProfessor] = useState(""); + const [messages, setMessages] = useState([]); + const [newMessage, setNewMessage] = useState(""); + const [darkMode, setDarkMode] = useState(true); + + const toggleDarkMode = () => { + setDarkMode(!darkMode); + }; + + useEffect(() => { + if (selectedCourse) { + const professor = dummyData.find( + (notice) => notice.course_name === selectedCourse + )?.professor_name; + setSelectedProfessor(professor || ""); + setMessages(dummyMessageData); + } + }, [selectedCourse]); + + useEffect(() => { + if (dummyData.length > 0) { + setSelectedCourse(dummyData[0].course_name); + } + }, []); + + useEffect(() => { + setMessages(dummyMessageData); + }, []); + + const handleCourseChange = (event: ChangeEvent) => { + setSelectedCourse(event.target.value); + }; + + const handleNewMessageChange = (event: ChangeEvent) => { + setNewMessage(event.target.value); + }; + + const handleSendMessage = (event: FormEvent) => { + event.preventDefault(); + const newMsg: Message = { + id: messages.length + 1, + sender: "You", + text: newMessage, + timestamp: new Date().toLocaleString(), + }; + setMessages([...messages, newMsg]); + setNewMessage(""); + + // 임시로 1초 후에 교수님의 답변이 오는 기능 + setTimeout(() => { + const professorReply: Message = { + id: messages.length + 2, + sender: "Professor", + text: "I received your message.", + timestamp: new Date().toLocaleString(), + }; + setMessages((prevMessages) => [...prevMessages, professorReply]); + }, 1000); + }; + + const courseOptions = Array.from( + new Set(dummyData.map((notice) => notice.course_name)) + ); + + return ( + <> +
+
+
메세지
+ +
+
+
+ +
+ {selectedProfessor && ( +
+ Professor: {selectedProfessor} +
+ )} +
+
+ {messages.map((msg) => ( +
+
+ + {msg.sender === "You" ? "You" : selectedProfessor} + + {msg.timestamp} +
+
{msg.text}
+
+ ))} +
+
+ + +
+
+ + ); +}; + +export default MessagePage; diff --git a/src/app/(main)/mypage/page.module.css b/src/app/(main)/mypage/page.module.css new file mode 100644 index 0000000..35ce9f9 --- /dev/null +++ b/src/app/(main)/mypage/page.module.css @@ -0,0 +1,93 @@ +.container { + padding: 20px 20px 100px 20px; + border-radius: 8px; +} + +.profileSection { + display: flex; + flex-direction: column; + align-items: center; + padding: 20px 0; + background-color: var(--orange-color); + color: #fff; + border-radius: 8px; + text-align: center; +} + +.profilePic { + border-radius: 50%; + border: 4px solid #fff; +} + +.userName { + font-size: 24px; + margin: 10px 0; +} + +.userRole { + font-size: 18px; + margin-bottom: 5px; +} + +.userId { + font-size: 16px; +} + +.infoSection, +.statisticsSection { + padding: 20px 0; +} + +.sectionTitle { + font-size: 22px; + color: var(--orange-color); + margin-bottom: 10px; +} + +.infoItem, +.statsItem { + display: flex; + justify-content: space-between; + padding: 10px 0; + border-bottom: 1px solid #eee; +} + +.infoLabel, +.statsLabel { + font-size: 16px; + color: var(--white-color); +} + +.infoValue, +.statsValue { + font-size: 16px; +} + +.linkSection { + padding-top: 30px; + display: flex; + flex-direction: column; + gap: 10px; +} + +.linkItem { + display: block; + text-align: start; + padding: 10px 0; + border-bottom: 1px solid #eee; + color: var(--white-color); + text-decoration: none; + font-size: 16px; + cursor: pointer; + transition: background-color 0.3s ease; +} + +.linkItem:hover { + color: var(--orange-color); +} + +@media (max-width: 430px) { + .container { + width: 320px; + } +} diff --git a/src/app/(main)/mypage/page.tsx b/src/app/(main)/mypage/page.tsx new file mode 100644 index 0000000..5f2282a --- /dev/null +++ b/src/app/(main)/mypage/page.tsx @@ -0,0 +1,80 @@ +"use client"; + +import { useAuthStore } from "@/store/authStore"; +import styles from "./page.module.css"; +import ProfilePic from "/public/icons/MyProfile.svg"; +import Link from "next/link"; +import { useRouter } from "next/navigation"; + +const MyPage = () => { + const user = useAuthStore((state) => state.user); + const logout = useAuthStore((state) => state.logout); + const router = useRouter(); + + const handleLogout = () => { + logout(); + router.push("/login"); + }; + + const handleDeleteAccount = () => { + logout(); + router.push("/onboarding"); + }; + + return ( +
+
+ +

{user?.name}

+

{user?.isStudent ? "학생" : "교수"}

+

{user?.studentId}

+
+
+

내 정보

+
+ 이름: + {user?.name} +
+
+ 역할: + + {user?.isStudent ? "학생" : "교수"} + +
+
+ 학번/교번: + {user?.studentId} +
+
+ 이메일: + {user?.email} +
+
+ +
+

컨테이너 사용시간 통계

+
+ 총 사용시간: + 50시간 +
+
+ 이번 학기 사용시간: + 20시간 +
+
+ +
+

로그인 관리

+
회원 정보 변경하기
+
+ 로그아웃 +
+
+ 탈퇴하기 +
+
+
+ ); +}; + +export default MyPage; diff --git a/src/app/(main)/notice/[id]/page.module.css b/src/app/(main)/notice/[id]/page.module.css new file mode 100644 index 0000000..0744320 --- /dev/null +++ b/src/app/(main)/notice/[id]/page.module.css @@ -0,0 +1,112 @@ +.container { + padding-bottom: 100px; + height: 100%; +} + +.header { + display: flex; + justify-content: space-between; + align-items: center; +} + +.headerTitle { + font-size: 24px; + font-family: "Pretendard-bold"; + padding: 10px 0; +} + +.courseInfo { + color: var(--orange-color); + font-size: 18px; +} + +.filterContainer { + min-width: 180px; + max-width: 700px; + padding-top: 30px; + display: flex; + gap: 20px; +} + +.courseButton { + width: 100%; + height: 40px; + display: flex; + background-color: var(--lightgray-color); + color: var(--white-color); + border-radius: 10px; + padding: 10px; + align-items: center; + justify-content: center; + gap: 10px; + border: none; + cursor: pointer; +} + +.active { + background-color: var(--orange-color); + color: var(--white-color); +} + +.notices { + display: flex; + flex-direction: column; + gap: 20px; + margin-top: 20px; +} + +.noticeItem { + border: 1px solid #ccc; + border-radius: 10px; + padding: 15px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); +} + +.noticeTitle { + font-size: 20px; + font-family: "Pretendard-bold"; + margin-bottom: 10px; +} + +.noticeBody { + font-size: 16px; + margin-bottom: 10px; +} + +.noticeFooter { + display: flex; + gap: 10px; + font-size: 14px; + color: #777; +} + +.courseName { + font-family: "Pretendard-bold"; +} + +.professorName { + font-style: italic; +} + +.postDate { + margin-left: auto; +} + +@media (max-width: 768px) { + .header { + flex-direction: column; + align-items: stretch; + gap: 10px; + } + .courseInfo { + display: flex; + } +} + +@media (max-width: 480px) { + .filterContainer { + flex-direction: column; + gap: 10px; + width: 320px; + } +} diff --git a/src/app/(main)/notice/[id]/page.tsx b/src/app/(main)/notice/[id]/page.tsx new file mode 100644 index 0000000..0cf8150 --- /dev/null +++ b/src/app/(main)/notice/[id]/page.tsx @@ -0,0 +1,107 @@ +"use client"; + +import { useParams } from "next/navigation"; +import { useState, useEffect, ChangeEvent } from "react"; +import styles from "./page.module.css"; +import dummyNoticeData from "@/data/dummy_notice_data.json"; +import FilterNotice from "@/components/notice/FilterNotice"; +import NoticeItem from "@/components/notice/NoticeItem"; + +interface NoticeData { + course_name: string; + professor_name: string; + notice_title: string; + notice_body: string; + post_date: string; +} + +export default function Notice() { + const param = useParams(); + const container = param.id; + const [selectedCourse, setSelectedCourse] = useState(""); + const [selectedProfessor, setSelectedProfessor] = useState(""); + const [_, setFilterOption] = useState(null); + + const handleFilterSelect = (option: string) => { + setFilterOption(option); + }; + + useEffect(() => { + if (container === "specific" && courseOptions.length > 0) { + const initialCourse = courseOptions[0]; + setSelectedCourse(initialCourse); + const initialProfessor = dummyNoticeData.find( + (notice) => notice.course_name === initialCourse + )?.professor_name; + setSelectedProfessor(initialProfessor || ""); + } + }, [container]); + + const title = + container === "all" ? "전체 과목 공지 보기" : "과목별 공지 보기"; + + const handleCourseSelect = (course: string) => { + setSelectedCourse(course); + const professor = dummyNoticeData.find( + (notice) => notice.course_name === course + )?.professor_name; + setSelectedProfessor(professor || ""); + }; + + const filteredNotices: NoticeData[] = + container === "all" + ? dummyNoticeData + : container === "specific" && selectedCourse + ? dummyNoticeData.filter( + (notice) => + notice.course_name.toLowerCase() === selectedCourse.toLowerCase() + ) + : []; + + const courseOptions: string[] = Array.from( + new Set(dummyNoticeData.map((notice) => notice.course_name)) + ); + + return ( +
+
+
+ {title} + {container === "specific" && selectedCourse && ( + + {` - ${selectedCourse} (${selectedProfessor})`} + + )} +
+ +
+ {container === "specific" && ( +
+ {courseOptions.map((course, index) => ( + + ))} +
+ )} +
+ {filteredNotices.map((notice, index) => ( + + ))} +
+
+ ); +} diff --git a/src/app/(onboarding)/layout.tsx b/src/app/(onboarding)/layout.tsx new file mode 100644 index 0000000..bf61686 --- /dev/null +++ b/src/app/(onboarding)/layout.tsx @@ -0,0 +1,13 @@ +import { ReactNode } from "react"; + +interface LayoutProps { + children: ReactNode; +} + +export default async function Layout({ children }: LayoutProps) { + return ( + <> +
{children}
+ + ); +} diff --git a/src/app/(onboarding)/login/page.module.css b/src/app/(onboarding)/login/page.module.css new file mode 100644 index 0000000..02ff5a6 --- /dev/null +++ b/src/app/(onboarding)/login/page.module.css @@ -0,0 +1,177 @@ +.container { + background-color: var(--black-color); + display: flex; + flex-direction: row; + min-height: 100dvh; +} + +.left { + width: 600px; + background-color: var(--gray-color); + border-top-right-radius: 40px; + border-bottom-right-radius: 40px; + padding: 25px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} +.leftContainer { + width: 430px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.logo { + display: flex; + gap: 40px; + align-items: center; + font-size: 24px; + font-family: "Pretendard-bold"; + color: var(--white-color); + text-decoration: none; +} + +.grayText { + color: var(--lightgray-color); + font-size: 18px; + padding-top: 15px; + font-family: "Pretendard-bold"; +} +.grayText2 { + color: var(--lightgray-color); + font-size: 16px; + padding-top: 15px; + font-family: "Pretendard"; +} + +.inputContainer { + padding-top: 30px; + display: flex; + flex-direction: column; + gap: 15px; + width: 100%; +} + +.input { + width: 100%; + height: 50px; + padding: 15px 0 15px 15px; + font-size: 16px; + border-radius: 10px; + border: 1px solid var(--lightgray-color); +} + +.inputBox { + display: flex; + position: relative; +} + +.icon { + position: absolute; + right: -0.5px; + top: 50%; + transform: translateY(-50%); +} + +.input:focus-visible { + outline: var(--orange-color); + outline-width: 10px; +} + +.forgotPassword { + margin-top: -5px; + color: var(--lightgray-color); + font-size: 16px; + text-align: right; + text-decoration: underline; + cursor: pointer; +} + +.loginButton { + width: 100%; + height: 50px; + background-color: var(--orange-color); + color: var(--white-color); + border-radius: 10px; + font-size: 16px; + font-family: "Pretendard-bold"; + margin-top: 30px; + display: flex; + justify-content: center; + align-items: center; + text-decoration: none; + cursor: pointer; +} +.divierContent { + display: flex; + flex-direction: row; + gap: 10px; +} + +.orDivider { + display: flex; + align-items: center; + text-align: center; + margin: 20px 0; +} + +.orDivider::before, +.orDivider::after { + content: ""; + flex: 1; + border-bottom: 1px solid var(--lightgray-color); + margin: 0 10px; +} + +.orDivider span { + font-size: 16px; + color: var(--lightgray-color); +} + +.signupButton { + width: 100%; + height: 50px; + border: 1px solid var(--orange-color); + color: var(--orange-color); + border-radius: 10px; + font-size: 16px; + font-family: "Pretendard-bold"; + display: flex; + justify-content: center; + align-items: center; + text-decoration: none; + cursor: pointer; +} + +.right { + flex: 1; +} +.background { + background-image: url("/icons/Background.svg"); + background-size: cover; + background-position: center; + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; +} + +@media (max-width: 768px) { + .left { + width: 100%; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + .leftContainer { + width: 100%; + } + + .right { + display: none; + } +} diff --git a/src/app/(onboarding)/login/page.tsx b/src/app/(onboarding)/login/page.tsx new file mode 100644 index 0000000..49b104e --- /dev/null +++ b/src/app/(onboarding)/login/page.tsx @@ -0,0 +1,98 @@ +"use client"; + +import { useState } from "react"; +import styles from "./page.module.css"; +import LogoIcon from "/public/icons/Logo1.svg"; +import EmailIcon from "/public/icons/Email.svg"; +import PasswordIcon from "/public/icons/Password.svg"; +import Link from "next/link"; +import { useAuthStore, authenticateUser } from "@/store/authStore"; +import { useRouter } from "next/navigation"; +import WarningModal from "@/components/common/WarningModal"; + +export default function Login() { + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [error, setError] = useState(""); + const [showModal, setShowModal] = useState(false); + const login = useAuthStore((state) => state.login); + + const router = useRouter(); + const handleSubmit = (e: any) => { + e.preventDefault(); + const user = authenticateUser(email, password); + + if (user) { + login(user); + router.push(user.isStudent ? "/container/all" : "/create-container"); + } else { + setError("Invalid email or password"); + setShowModal(true); + } + }; + + const closeModal = () => { + setShowModal(false); + setError(""); + }; + + return ( +
+
+
+
+ + + +
DevLatte
+
+
Login into your account
+
+ +
+ setEmail(e.target.value)} + /> + +
+
+
+ +
+ setPassword(e.target.value)} + /> + +
+
Forgot password?
+ +
+ or +
+ + Sign up now + +
+
+
+ {showModal && } +
+
+
+
+ ); +} diff --git a/src/app/(onboarding)/onboarding/page.module.css b/src/app/(onboarding)/onboarding/page.module.css new file mode 100644 index 0000000..c62e919 --- /dev/null +++ b/src/app/(onboarding)/onboarding/page.module.css @@ -0,0 +1,78 @@ +.container { + min-height: 100dvh; + background-color: var(--black-color); + display: flex; + flex-direction: column; +} + +.mainContainer { + display: flex; + flex: 1; + flex-direction: row; + /* background-color: var(--lightgray-color); */ + margin: 0 140px; + justify-content: center; + align-items: center; +} + +.leftContainer { + flex: 1; + min-width: 430px; + width: 210px; + gap: 100px; +} + +.rightContainer { + flex: 1; +} + +.headerText { + font-size: 50px; + font-family: "Pretendard-bold"; + color: var(--lightgray2-color); +} +.bodyText { + margin-top: 100px; + font-size: 20px; + font-family: "Pretendar-Medium"; +} +.loginButton { + margin-top: 60px; + background-color: var(--orange-color); + width: 320px; + height: 75px; + text-decoration: none; + border: none; + border-radius: 16px; + color: var(--white-color); + font-size: 20px; + cursor: pointer; +} + +.logo { + height: 100%; + width: 100%; +} + +@media (max-width: 800px) { + .mainContainer { + margin: 0 40px; + } + .rightContainer { + display: none; + } + .leftContainer { + display: flex; + flex-direction: column; + text-align: center; + align-items: center; + justify-content: center; + } +} + +@media (max-width: 600px) { + .leftContainer { + scale: 0.8; + gap: 50px; + } +} diff --git a/src/app/(onboarding)/onboarding/page.tsx b/src/app/(onboarding)/onboarding/page.tsx new file mode 100644 index 0000000..fc27fe1 --- /dev/null +++ b/src/app/(onboarding)/onboarding/page.tsx @@ -0,0 +1,39 @@ +import React from "react"; +import styles from "./page.module.css"; +import TopNavBar from "@/components/onboarding/TopNavBar"; +import LogoBig from "/public/icons/LogoBig.png"; +import Image from "next/image"; +import Link from "next/link"; + +export default function page() { + return ( +
+ +
+
+
+ DevRoom으로 +
+ 손쉽게 과제 하자! +
A to Z까지 +
+
+ 별도의 설정없이 +
서버 접속부터 과제제출까지!
+
+ 컨테이너 서버에 바로 접근하여,
+ 손쉽게 과제 환경에 접속해보세요! +
+ + + +
+
+ logo +
+
+
+ ); +} diff --git a/src/app/(onboarding)/signup/page.module.css b/src/app/(onboarding)/signup/page.module.css new file mode 100644 index 0000000..5f5547a --- /dev/null +++ b/src/app/(onboarding)/signup/page.module.css @@ -0,0 +1,144 @@ +.container { + background-color: var(--black-color); + display: flex; + flex-direction: row; + min-height: 100dvh; +} + +.left { + flex: 1; + background-color: var(--gray-color); +} +.background { + background-image: url("/icons/Background.svg"); + background-size: cover; + background-position: center; + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; +} + +.right { + width: 600px; + background-color: var(--gray-color); + border-top-left-radius: 40px; + border-bottom-left-radius: 40px; + padding: 25px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.rightContainer { + width: 430px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.logo { + display: flex; + gap: 40px; + align-items: center; + font-size: 24px; + font-family: "Pretendard-bold"; +} + +.grayText { + color: var(--lightgray-color); + font-size: 18px; + padding-top: 15px; + font-family: "Pretendard-bold"; +} + +.grayText2 { + color: var(--lightgray-color); + font-size: 16px; + padding-top: 15px; + font-family: "Pretendard"; +} + +.inputContainer { + padding-top: 20px; + display: flex; + flex-direction: column; + gap: 15px; + width: 100%; +} + +.input { + width: 100%; + height: 50px; + padding: 15px 0 15px 15px; + font-size: 16px; + border-radius: 10px; + border: 1px solid var(--lightgray-color); +} + +.inputBox { + display: flex; + position: relative; +} + +.icon { + position: absolute; + right: -0.5px; + top: 50%; + transform: translateY(-50%); +} + +.input:focus-visible { + outline: var(--orange-color); + outline-width: 10px; +} + +.createAccountButton { + width: 100%; + height: 50px; + margin-top: 60px; + background-color: var(--orange-color); + color: var(--white-color); + border-radius: 10px; + font-size: 16px; + font-family: "Pretendard-bold"; + display: flex; + justify-content: center; + align-items: center; + text-decoration: none; + cursor: pointer; +} + +.linkContainer { + padding-top: 15px; + display: flex; + justify-content: flex-end; + align-items: center; + gap: 10px; + width: 100%; +} + +.textAlready { + color: var(--lightgray-color); + font-size: 16px; + font-family: "Pretendard"; +} + +.loginLink { + color: var(--orange-color); +} + +@media (max-width: 768px) { + .right { + border-radius: 0px; + } + .rightContainer { + width: 100%; + } + .left { + display: none; + } +} diff --git a/src/app/(onboarding)/signup/page.tsx b/src/app/(onboarding)/signup/page.tsx new file mode 100644 index 0000000..9874724 --- /dev/null +++ b/src/app/(onboarding)/signup/page.tsx @@ -0,0 +1,78 @@ +import styles from "./page.module.css"; +import LogoIcon from "/public/icons/Logo1.svg"; +import EmailIcon from "/public/icons/Email.svg"; +import PasswordIcon from "/public/icons/Password.svg"; +import UsernameIcon from "/public/icons/Username.svg"; +import Link from "next/link"; + +export default function signup() { + return ( +
+
+
+
+
+
+
+ + + +
DevLatte
+
+
Create your Account
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+ + Create Account + +
+
already have an account?
+ + Login + +
+
+
+
+ ); +} diff --git a/src/app/(professor)/check-container/page.module.css b/src/app/(professor)/check-container/page.module.css new file mode 100644 index 0000000..bb07d33 --- /dev/null +++ b/src/app/(professor)/check-container/page.module.css @@ -0,0 +1,66 @@ +.container { + padding-bottom: 100px; +} + +.headerTitle { + font-size: 24px; + font-family: "Pretendard-bold"; + padding: 10px 0; +} + +.header { + display: flex; + align-items: center; + justify-content: space-between; + flex-wrap: wrap; + padding-bottom: 20px; +} + +.filter { + display: flex; + justify-content: center; + align-items: center; +} + +.filter label { + margin-right: 10px; + font-size: 18px; + color: var(--orange-color); +} + +.filter select { + padding: 5px; + font-size: 16px; + border-radius: 4px; + border: 1px solid #ccc; +} + +.filter select:focus-visible { + outline: var(--orange-color); + outline-width: 5px; +} + +.tableContainer { + display: block; +} + +@media (max-width: 768px) { + .header { + flex-direction: column; + align-items: flex-start; + } + + .filter { + flex-direction: column; + align-items: flex-start; + } + + .filter label, + .filter select { + margin-bottom: 10px; + } + + .tableContainer { + display: none; + } +} diff --git a/src/app/(professor)/check-container/page.tsx b/src/app/(professor)/check-container/page.tsx new file mode 100644 index 0000000..041e7e7 --- /dev/null +++ b/src/app/(professor)/check-container/page.tsx @@ -0,0 +1,67 @@ +"use client"; +import { useState } from "react"; +import styles from "./page.module.css"; +import data from "@/data/dummy_check_data.json"; +import PodTable from "@/components/check/PodTable"; +import GridComponent from "@/components/check/PodGrid"; + +interface PodData { + name: string; + ip: string; + labels: { + app: string; + class_id: string; + pod_template_hash: string; + professor_id: string; + student_id: string; + vscode: string; + ssh: string; + }; + creationTimestamp: string; + status: string; +} + +const CheckPage = () => { + const [filterClassId, setFilterClassId] = useState(""); + + const handleFilterChange = (e: React.ChangeEvent) => { + setFilterClassId(e.target.value); + }; + + const filteredData = data.filter((pod: PodData) => { + return filterClassId === "" || pod.labels.class_id === filterClassId; + }); + + const classIds = Array.from( + new Set(data.map((pod: PodData) => pod.labels.class_id)) + ); + + return ( +
+
+
Pod 조회 페이지
+
+ + +
+
+
+ +
+ +
+ ); +}; + +export default CheckPage; diff --git a/src/app/(professor)/create-container/page.module.css b/src/app/(professor)/create-container/page.module.css new file mode 100644 index 0000000..817b35a --- /dev/null +++ b/src/app/(professor)/create-container/page.module.css @@ -0,0 +1,95 @@ +.container { + display: flex; + flex-direction: row; + background-color: var(--lightgray-color); + padding: 40px; + border-radius: 30px; +} + +.leftContainer { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding-right: 50px; +} + +.logoText { + font-size: 30px; + font-family: "Pretendard-bold"; + padding: 50px 0 15px; +} +.grayText { + color: var(--gray-color); + font-size: 16px; + font-family: "Pretendard-bold"; +} + +.rightContainer { + flex: 1; + padding: 40px 0 20px; + max-width: 800px; +} + +.title { + font-size: 24px; + font-family: "Pretendard-bold"; + padding: 10px 0; + margin-bottom: 40px; +} + +.form { + display: flex; + flex-direction: column; + gap: 15px; +} + +.formGroup { + display: flex; + flex-direction: column; +} + +.formGroup label { + margin-bottom: 5px; + font-size: 16px; + font-family: "Pretendard-bold"; + color: var(--gray-color); +} + +.formGroup input, +.formGroup select { + padding: 8px; + font-size: 14px; + font-family: "Pretendard-Medium"; + border: 1px solid #ccc; + border-radius: 12px; +} +.td { + font-family: "Pretendard-Medium"; +} + +.submitButton { + margin-top: 30px; + padding: 10px 15px; + font-size: 16px; + font-family: "Pretendard-Medium"; + color: white; + background-color: var(--orange-color); + border: none; + border-radius: 12px; + cursor: pointer; +} + +@media (max-width: 768px) { + .leftContainer { + display: none; + } +} + +@media (max-width: 430px) { + .container { + width: 70%; + padding: 10px 20px; + } +} diff --git a/src/app/(professor)/create-container/page.tsx b/src/app/(professor)/create-container/page.tsx new file mode 100644 index 0000000..330c434 --- /dev/null +++ b/src/app/(professor)/create-container/page.tsx @@ -0,0 +1,95 @@ +"use client"; +import { useState } from "react"; +import styles from "./page.module.css"; +import Logo2Icon from "/public/icons/Logo2.svg"; + +const CreateContainerPage = () => { + const [classId, setClassId] = useState(""); + const [type, setType] = useState("vscode"); + const [port, setPort] = useState(""); + const [command, setCommand] = useState(""); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + const containerData = { + classId, + type, + port: type === "vscode" ? port : undefined, + command: type === "ssh" ? command : undefined, + }; + // console.log("Container Data:", containerData); + }; + + return ( + <> +

컨테이너 생성

+
+
+ +
Create Container
+
+ Create a container for your class +
+
+
+
+
+ + setClassId(e.target.value)} + required + /> +
+
+ + +
+ {type === "ssh" && ( +
+ + setCommand(e.target.value)} + required + /> +
+ )} + {type === "vscode" && ( +
+ + setPort(e.target.value)} + required + /> +
+ )} + +
+
+
+ + ); +}; + +export default CreateContainerPage; diff --git a/src/app/(professor)/edit-container/page.module.css b/src/app/(professor)/edit-container/page.module.css new file mode 100644 index 0000000..6046c56 --- /dev/null +++ b/src/app/(professor)/edit-container/page.module.css @@ -0,0 +1,108 @@ +/* EditContainerPage.module.css */ + +.container { + display: flex; + flex-direction: row; + background-color: var(--lightgray-color); + padding: 40px; + border-radius: 30px; +} + +.leftContainer { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding-right: 50px; +} + +.logoText { + font-size: 30px; + font-family: "Pretendard-bold"; + padding: 50px 0 15px; +} + +.grayText { + color: var(--gray-color); + font-size: 16px; + font-family: "Pretendard-bold"; +} + +.rightContainer { + flex: 1; + padding: 40px 0 20px; + max-width: 800px; +} + +.title { + font-size: 24px; + font-family: "Pretendard-bold"; + padding: 10px 0; + margin-bottom: 40px; +} + +.form { + display: flex; + flex-direction: column; + gap: 15px; +} + +.formGroup { + display: flex; + flex-direction: column; +} + +.formGroup label { + margin-bottom: 5px; + font-size: 16px; + font-family: "Pretendard-bold"; + color: var(--gray-color); +} + +.formGroup input, +.formGroup select { + padding: 8px; + font-size: 14px; + border: 1px solid #ccc; + border-radius: 12px; +} + +.buttonGroup { + display: flex; + gap: 20px; + justify-content: space-between; +} + +.saveButton, +.deleteButton { + margin-top: 30px; + padding: 10px 15px; + font-size: 16px; + color: white; + border: none; + border-radius: 12px; + cursor: pointer; + flex: 1; +} + +.saveButton { + background-color: var(--orange-color); +} + +.deleteButton { + background-color: var(--gray-color); +} + +@media (max-width: 768px) { + .leftContainer { + display: none; + } +} + +@media (max-width: 430px) { + .container { + width: 70%; + padding: 10px 20px; + } +} diff --git a/src/app/(professor)/edit-container/page.tsx b/src/app/(professor)/edit-container/page.tsx new file mode 100644 index 0000000..35ecff7 --- /dev/null +++ b/src/app/(professor)/edit-container/page.tsx @@ -0,0 +1,144 @@ +"use client"; +import { useState } from "react"; +import styles from "./page.module.css"; +import Logo2Icon from "/public/icons/Logo2.svg"; +import dummy_edit_data from "@/data/dummy_edit_data.json"; +import WarningModal from "@/components/common/WarningModal"; + +const EditContainerPage = () => { + const [classId, setClassId] = useState(""); + const [type, setType] = useState(""); + const [port, setPort] = useState(""); + const [command, setCommand] = useState(""); + const [showSaveModal, setShowSaveModal] = useState(false); + const [showDeleteModal, setShowDeleteModal] = useState(false); + + const mockData = dummy_edit_data; + + const handleClassIdChange = (e: React.ChangeEvent) => { + const selectedId = e.target.value; + setClassId(selectedId); + + const selectedData = mockData.find((data) => data.id === selectedId); + if (selectedData) { + setType(selectedData.type); + setPort(selectedData.port); + setCommand(selectedData.command); + } else { + setType(""); + setPort(""); + setCommand(""); + } + }; + + const handleSave = (e: React.FormEvent) => { + e.preventDefault(); + const containerData = { + classId, + type, + port: type === "vscode" ? port : undefined, + command: type === "ssh" ? command : undefined, + }; + console.log("Container Data:", containerData); + setShowSaveModal(true); + }; + + const handleDelete = () => { + setShowDeleteModal(true); + }; + + return ( + <> +

컨테이너 수정 및 삭제

+
+
+ +
Edit Container
+
Edit or delete your container
+
+
+
+
+ + +
+
+ + +
+
+ + setCommand(e.target.value)} + required + disabled={type !== "ssh"} + /> +
+
+ + setPort(e.target.value)} + required + disabled={type !== "vscode"} + /> +
+
+ + +
+
+
+
+ {showSaveModal && ( + setShowSaveModal(false)} + /> + )} + {showDeleteModal && ( + setShowDeleteModal(false)} + /> + )} + + ); +}; + +export default EditContainerPage; diff --git a/src/app/(professor)/layout.module.css b/src/app/(professor)/layout.module.css new file mode 100644 index 0000000..cdaa046 --- /dev/null +++ b/src/app/(professor)/layout.module.css @@ -0,0 +1,148 @@ +.layout { + display: flex; + min-height: 100dvh; + height: 100%; + background-color: var(--gray-color); +} + +.sidebar { + width: 310px; + min-width: 310px; + padding: 20px; + transition: transform 0.3s ease, opacity 0.3s ease; + transform: translateX(0); + height: 100%; + background-color: var(--gray-color); +} + +.sidebar.closed { + transform: translateX(-100%); + opacity: 0; +} + +.logo { + display: flex; + align-items: center; + justify-content: space-between; +} + +.school { + font-size: 24px; + font-family: "Pretendard-bold"; + height: 80px; + display: flex; + align-items: center; +} + +.userContainer { + display: flex; + align-items: center; + padding-bottom: 20px; + gap: 10px; + border-bottom: 1px dashed var(--lightgray-color); +} + +.userInfo { + display: flex; + padding-bottom: 5px; + gap: 5px; + font-family: "Pretendard-bold"; + font-size: 20px; +} + +.studentsId { + font-family: "Pretendard-Regular"; + font-size: 16px; +} + +.studentId { + font-family: "Pretendard-Regular"; + font-size: 18px; +} + +.menu { + padding: 50px 0 20px 0; + display: flex; + flex-direction: column; + gap: 30px; +} + +.menuItem { + display: flex; + align-items: center; + gap: 15px; + height: 60px; + padding: 10px; + border-radius: 10px; + transition: color 0.3s ease, background-color 0.3s ease; +} + +.menuText { + font-size: 20px; + font-family: "Pretendard-bold"; +} + +.subMenu { + padding-left: 20px; + margin-top: -20px; +} + +.subMenu div { + font-family: "Pretendard-Medium"; + font-size: 18px; +} + +.down { + margin-left: auto; +} + +.menu a { + display: block; + color: var(--white-color); + text-decoration: none; + font-size: 20px; + font-family: "Pretendard-bold"; +} + +.menuItem:hover { + color: var(--orange-color); +} + +.menuItem.active { + background-color: var(--orange50-color); +} + +.content { + flex-grow: 1; + background-color: var(--black-color); + padding: 40px 40px 0; + transition: margin-left 0.3s ease; + min-width: 500px; +} + +.left { + background-color: var(--black-color); + width: 100%; + height: 100dvh; + transition: 0.15s ease; +} + +.topName { + display: flex; + flex-direction: row; + align-items: center; + padding: 50px 40px 0; + font-size: 24px; + font-family: "Pretendard-Medium"; + gap: 10px; + background-color: var(--black-color); +} + +.left.shifted { + margin-left: -310px; + background-color: var(--black-color); +} + +.iconButton { + cursor: pointer; +} diff --git a/src/app/(professor)/layout.tsx b/src/app/(professor)/layout.tsx new file mode 100644 index 0000000..a3873f9 --- /dev/null +++ b/src/app/(professor)/layout.tsx @@ -0,0 +1,186 @@ +"use client"; + +import { ReactNode, useEffect, useState } from "react"; +import styles from "./layout.module.css"; +import { useAuthStore } from "@/store/authStore"; +import Link from "next/link"; +import { redirect, usePathname } from "next/navigation"; +import Image from "next/image"; +import LeftArrowIcon from "/public/icons/LeftArrow.svg"; +import HamburgerIcon from "/public/icons/Hamburger.svg"; + +interface LayoutProps { + children: ReactNode; +} + +export default function Layout({ children }: LayoutProps) { + const user = useAuthStore((state) => state.user); + const isLoggedIn = useAuthStore((state) => state.isLoggedIn); + const isLoading = useAuthStore((state) => state.isLoading); + const [isSidebarOpen, setSidebarOpen] = useState(true); + + useEffect(() => { + if (!isLoggedIn && !isLoading) { + redirect("/onboarding"); + } + }, [isLoggedIn, isLoading]); + + const navigation = usePathname(); + + const isActive = (path: string) => { + return navigation === path ? styles.active : ""; + }; + + const toggleSidebar = () => { + setSidebarOpen(!isSidebarOpen); + }; + + const handleResize = () => { + if (window.innerWidth <= 768) { + setSidebarOpen(false); + } else { + setSidebarOpen(true); + } + }; + + useEffect(() => { + handleResize(); // 초기 실행 시 한 번 호출 + window.addEventListener("resize", handleResize); + return () => { + window.removeEventListener("resize", handleResize); + }; + }, []); + + return ( +
+ {/* 사이드바 */} +
+
+
성균관대학교
+ +
+ +
+ myprofile +
+
+
{user?.name}
+
{user?.isStudent ? "- 학생" : " - 교수"}
+
+
{user?.studentId}
+
+
+
+
+ container +
스페이스
+ container +
+
+ +
+
컨테이너 생성
+
+ + +
+
컨테이너 수정 및 삭제
+
+ +
+ +
+ help +
조회
+
+ +
+ notice +
공지사항
+
+
+ community +
메세지
+
+ +
+ mypage +
마이페이지
+
+ +
+
+ + {/* 메인 컨텐츠 */} +
+
+ {!isSidebarOpen && ( + + )} +
{user?.name}
+
/ {user?.studentId}
+
+
+ {children} +
+
+
+ ); +} diff --git a/src/app/(professor)/professor-page/page.module.css b/src/app/(professor)/professor-page/page.module.css new file mode 100644 index 0000000..35ce9f9 --- /dev/null +++ b/src/app/(professor)/professor-page/page.module.css @@ -0,0 +1,93 @@ +.container { + padding: 20px 20px 100px 20px; + border-radius: 8px; +} + +.profileSection { + display: flex; + flex-direction: column; + align-items: center; + padding: 20px 0; + background-color: var(--orange-color); + color: #fff; + border-radius: 8px; + text-align: center; +} + +.profilePic { + border-radius: 50%; + border: 4px solid #fff; +} + +.userName { + font-size: 24px; + margin: 10px 0; +} + +.userRole { + font-size: 18px; + margin-bottom: 5px; +} + +.userId { + font-size: 16px; +} + +.infoSection, +.statisticsSection { + padding: 20px 0; +} + +.sectionTitle { + font-size: 22px; + color: var(--orange-color); + margin-bottom: 10px; +} + +.infoItem, +.statsItem { + display: flex; + justify-content: space-between; + padding: 10px 0; + border-bottom: 1px solid #eee; +} + +.infoLabel, +.statsLabel { + font-size: 16px; + color: var(--white-color); +} + +.infoValue, +.statsValue { + font-size: 16px; +} + +.linkSection { + padding-top: 30px; + display: flex; + flex-direction: column; + gap: 10px; +} + +.linkItem { + display: block; + text-align: start; + padding: 10px 0; + border-bottom: 1px solid #eee; + color: var(--white-color); + text-decoration: none; + font-size: 16px; + cursor: pointer; + transition: background-color 0.3s ease; +} + +.linkItem:hover { + color: var(--orange-color); +} + +@media (max-width: 430px) { + .container { + width: 320px; + } +} diff --git a/src/app/(professor)/professor-page/page.tsx b/src/app/(professor)/professor-page/page.tsx new file mode 100644 index 0000000..c32f80c --- /dev/null +++ b/src/app/(professor)/professor-page/page.tsx @@ -0,0 +1,79 @@ +"use client"; + +import { useAuthStore } from "@/store/authStore"; +import styles from "./page.module.css"; +import ProfilePic from "/public/icons/MyProfile.svg"; +import { useRouter } from "next/navigation"; + +const MyPage = () => { + const user = useAuthStore((state) => state.user); + const logout = useAuthStore((state) => state.logout); + const router = useRouter(); + + const handleLogout = () => { + logout(); + router.push("/login"); + }; + + const handleDeleteAccount = () => { + logout(); + router.push("/onboarding"); + }; + + return ( +
+
+ +

{user?.name}

+

{user?.isStudent ? "학생" : "교수"}

+

{user?.studentId}

+
+
+

내 정보

+
+ 이름: + {user?.name} +
+
+ 역할: + + {user?.isStudent ? "학생" : "교수"} + +
+
+ 학번/교번: + {user?.studentId} +
+
+ 이메일: + {user?.email} +
+
+ +
+

컨테이너 정보

+
+ 운영중인 컨테이너 개수: + 5개 +
+
+ 사용된 컨테이너 개수: + 67개 +
+
+ +
+

로그인 관리

+
회원 정보 변경하기
+
+ 로그아웃 +
+
+ 탈퇴하기 +
+
+
+ ); +}; + +export default MyPage; diff --git a/src/app/favicon.ico b/src/app/favicon.ico deleted file mode 100644 index 718d6fe..0000000 Binary files a/src/app/favicon.ico and /dev/null differ diff --git a/src/app/fonts/Pretendard-Bold.ttf b/src/app/fonts/Pretendard-Bold.ttf new file mode 100644 index 0000000..fb07fc6 Binary files /dev/null and b/src/app/fonts/Pretendard-Bold.ttf differ diff --git a/src/app/fonts/Pretendard-Medium.ttf b/src/app/fonts/Pretendard-Medium.ttf new file mode 100644 index 0000000..1db67c6 Binary files /dev/null and b/src/app/fonts/Pretendard-Medium.ttf differ diff --git a/src/app/fonts/Pretendard-Regular.ttf b/src/app/fonts/Pretendard-Regular.ttf new file mode 100644 index 0000000..01147e9 Binary files /dev/null and b/src/app/fonts/Pretendard-Regular.ttf differ diff --git a/src/app/globals.css b/src/app/globals.css index f4bd77c..d20fdba 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,76 +1,34 @@ :root { --max-width: 1100px; --border-radius: 12px; - --font-mono: ui-monospace, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono", + /* --font-mono: ui-monospace, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono", "Roboto Mono", "Oxygen Mono", "Ubuntu Monospace", "Source Code Pro", - "Fira Mono", "Droid Sans Mono", "Courier New", monospace; - - --foreground-rgb: 0, 0, 0; - --background-start-rgb: 214, 219, 220; - --background-end-rgb: 255, 255, 255; - - --primary-glow: conic-gradient( - from 180deg at 50% 50%, - #16abff33 0deg, - #0885ff33 55deg, - #54d6ff33 120deg, - #0071ff33 160deg, - transparent 360deg - ); - --secondary-glow: radial-gradient( - rgba(255, 255, 255, 1), - rgba(255, 255, 255, 0) - ); - - --tile-start-rgb: 239, 245, 249; - --tile-end-rgb: 228, 232, 233; - --tile-border: conic-gradient( - #00000080, - #00000040, - #00000030, - #00000020, - #00000010, - #00000010, - #00000080 - ); - - --callout-rgb: 238, 240, 241; - --callout-border-rgb: 172, 175, 176; - --card-rgb: 180, 185, 188; - --card-border-rgb: 131, 134, 135; + "Fira Mono", "Droid Sans Mono", "Courier New", monospace; */ + + /* 색상 지정 */ + --gray-color: #2d2d2d; + --orange-color: #fd7401; + --black-color: #1d1d1d; + --lightgray-color: #8d8d8d; + --lightgray2-color: #d9d9d9; + --blue-color: #0099ff; + --white-color: #ffffff; + --green-color: #1d6e00; + --orange50-color: rgba(253, 116, 1, 0.7); } -@media (prefers-color-scheme: dark) { - :root { - --foreground-rgb: 255, 255, 255; - --background-start-rgb: 0, 0, 0; - --background-end-rgb: 0, 0, 0; - - --primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0)); - --secondary-glow: linear-gradient( - to bottom right, - rgba(1, 65, 255, 0), - rgba(1, 65, 255, 0), - rgba(1, 65, 255, 0.3) - ); - - --tile-start-rgb: 2, 13, 46; - --tile-end-rgb: 2, 5, 19; - --tile-border: conic-gradient( - #ffffff80, - #ffffff40, - #ffffff30, - #ffffff20, - #ffffff10, - #ffffff10, - #ffffff80 - ); +@font-face { + font-family: "Pretendard"; + font-weight: 400; + font-style: normal; + src: url("/fonts/Pretendard-Medium.ttf") format("ttf"); +} - --callout-rgb: 20, 20, 20; - --callout-border-rgb: 108, 108, 108; - --card-rgb: 100, 100, 100; - --card-border-rgb: 200, 200, 200; - } +@font-face { + font-family: "Pretendard"; + font-weight: 700; + font-style: normal; + src: url("/fonts/Pretendard-Bold.ttf") format("ttf"); } * { @@ -83,25 +41,7 @@ html, body { max-width: 100vw; overflow-x: hidden; -} - -body { - color: rgb(var(--foreground-rgb)); - background: linear-gradient( - to bottom, - transparent, - rgb(var(--background-end-rgb)) - ) - rgb(var(--background-start-rgb)); -} - -a { - color: inherit; - text-decoration: none; -} - -@media (prefers-color-scheme: dark) { - html { - color-scheme: dark; - } + font-family: "Pretendard", sans-serif; + color: var(--white-color); + background-color: var(--gray-color); } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 3314e47..921cf9b 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,22 +1,51 @@ import type { Metadata } from "next"; -import { Inter } from "next/font/google"; +import localFont from "next/font/local"; import "./globals.css"; -const inter = Inter({ subsets: ["latin"] }); - export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", + title: { + default: "DevRoom", + template: "DevRoom| %s", + }, + icons: [ + { url: "/favicon.ico", sizes: "any" }, + { + url: "/favicon.png", + sizes: "32x32", + type: "image/png", + }, + ], }; +const pretendardBold = localFont({ + src: "./fonts/Pretendard-Bold.ttf", + display: "swap", + weight: "700", +}); + +const pretendardMedium = localFont({ + src: "./fonts/Pretendard-Medium.ttf", + display: "swap", + weight: "300", +}); +const pretendard = localFont({ + src: "./fonts/Pretendard-Regular.ttf", + display: "swap", + weight: "300", +}); + export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { return ( - - {children} + + + {children} + ); } diff --git a/src/app/page.module.css b/src/app/page.module.css deleted file mode 100644 index 5c4b1e6..0000000 --- a/src/app/page.module.css +++ /dev/null @@ -1,230 +0,0 @@ -.main { - display: flex; - flex-direction: column; - justify-content: space-between; - align-items: center; - padding: 6rem; - min-height: 100vh; -} - -.description { - display: inherit; - justify-content: inherit; - align-items: inherit; - font-size: 0.85rem; - max-width: var(--max-width); - width: 100%; - z-index: 2; - font-family: var(--font-mono); -} - -.description a { - display: flex; - justify-content: center; - align-items: center; - gap: 0.5rem; -} - -.description p { - position: relative; - margin: 0; - padding: 1rem; - background-color: rgba(var(--callout-rgb), 0.5); - border: 1px solid rgba(var(--callout-border-rgb), 0.3); - border-radius: var(--border-radius); -} - -.code { - font-weight: 700; - font-family: var(--font-mono); -} - -.grid { - display: grid; - grid-template-columns: repeat(4, minmax(25%, auto)); - max-width: 100%; - width: var(--max-width); -} - -.card { - padding: 1rem 1.2rem; - border-radius: var(--border-radius); - background: rgba(var(--card-rgb), 0); - border: 1px solid rgba(var(--card-border-rgb), 0); - transition: background 200ms, border 200ms; -} - -.card span { - display: inline-block; - transition: transform 200ms; -} - -.card h2 { - font-weight: 600; - margin-bottom: 0.7rem; -} - -.card p { - margin: 0; - opacity: 0.6; - font-size: 0.9rem; - line-height: 1.5; - max-width: 30ch; - text-wrap: balance; -} - -.center { - display: flex; - justify-content: center; - align-items: center; - position: relative; - padding: 4rem 0; -} - -.center::before { - background: var(--secondary-glow); - border-radius: 50%; - width: 480px; - height: 360px; - margin-left: -400px; -} - -.center::after { - background: var(--primary-glow); - width: 240px; - height: 180px; - z-index: -1; -} - -.center::before, -.center::after { - content: ""; - left: 50%; - position: absolute; - filter: blur(45px); - transform: translateZ(0); -} - -.logo { - position: relative; -} -/* Enable hover only on non-touch devices */ -@media (hover: hover) and (pointer: fine) { - .card:hover { - background: rgba(var(--card-rgb), 0.1); - border: 1px solid rgba(var(--card-border-rgb), 0.15); - } - - .card:hover span { - transform: translateX(4px); - } -} - -@media (prefers-reduced-motion) { - .card:hover span { - transform: none; - } -} - -/* Mobile */ -@media (max-width: 700px) { - .content { - padding: 4rem; - } - - .grid { - grid-template-columns: 1fr; - margin-bottom: 120px; - max-width: 320px; - text-align: center; - } - - .card { - padding: 1rem 2.5rem; - } - - .card h2 { - margin-bottom: 0.5rem; - } - - .center { - padding: 8rem 0 6rem; - } - - .center::before { - transform: none; - height: 300px; - } - - .description { - font-size: 0.8rem; - } - - .description a { - padding: 1rem; - } - - .description p, - .description div { - display: flex; - justify-content: center; - position: fixed; - width: 100%; - } - - .description p { - align-items: center; - inset: 0 0 auto; - padding: 2rem 1rem 1.4rem; - border-radius: 0; - border: none; - border-bottom: 1px solid rgba(var(--callout-border-rgb), 0.25); - background: linear-gradient( - to bottom, - rgba(var(--background-start-rgb), 1), - rgba(var(--callout-rgb), 0.5) - ); - background-clip: padding-box; - backdrop-filter: blur(24px); - } - - .description div { - align-items: flex-end; - pointer-events: none; - inset: auto 0 0; - padding: 2rem; - height: 200px; - background: linear-gradient( - to bottom, - transparent 0%, - rgb(var(--background-end-rgb)) 40% - ); - z-index: 1; - } -} - -/* Tablet and Smaller Desktop */ -@media (min-width: 701px) and (max-width: 1120px) { - .grid { - grid-template-columns: repeat(2, 50%); - } -} - -@media (prefers-color-scheme: dark) { - .vercelLogo { - filter: invert(1); - } - - .logo { - filter: invert(1) drop-shadow(0 0 0.3rem #ffffff70); - } -} - -@keyframes rotate { - from { - transform: rotate(360deg); - } - to { - transform: rotate(0deg); - } -} diff --git a/src/app/page.tsx b/src/app/page.tsx index d2c63a4..244ad0f 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,95 +1,5 @@ -import Image from "next/image"; -import styles from "./page.module.css"; +import { redirect } from "next/navigation"; -export default function Home() { - return ( -
-
-

- Get started by editing  - src/app/page.tsx -

- -
- -
- Next.js Logo -
- - -
- ); +export default function Main() { + redirect("/onboarding"); } diff --git a/src/components/check/PodGrid.module.css b/src/components/check/PodGrid.module.css new file mode 100644 index 0000000..a87b263 --- /dev/null +++ b/src/components/check/PodGrid.module.css @@ -0,0 +1,41 @@ +.gridContainer { + display: none; +} + +@media (max-width: 768px) { + .gridContainer { + display: grid; + grid-template-columns: 1fr; + gap: 10px; + } + + .gridItem { + border-radius: 12px; + padding: 20px; + border: 1px solid var(--orange-color); + color: var(--lightgray2-color); + } +} + +@media (max-width: 430px) { + .gridContainer { + width: 300px; + padding: 0; + } +} + +.statusRunning { + display: inline-block; + width: 12px; + height: 12px; + background-color: green; + border-radius: 50%; +} + +.statusNotRunning { + display: inline-block; + width: 12px; + height: 12px; + background-color: red; + border-radius: 50%; +} diff --git a/src/components/check/PodGrid.tsx b/src/components/check/PodGrid.tsx new file mode 100644 index 0000000..8aefad5 --- /dev/null +++ b/src/components/check/PodGrid.tsx @@ -0,0 +1,59 @@ +import React from "react"; +import styles from "./PodGrid.module.css"; + +interface PodData { + name: string; + ip: string; + labels: { + app: string; + class_id: string; + pod_template_hash: string; + professor_id: string; + student_id: string; + vscode: string; + ssh: string; + }; + creationTimestamp: string; + status: string; +} + +interface GridComponentProps { + filteredData: PodData[]; +} + +const GridComponent = ({ filteredData }: GridComponentProps) => { + return ( +
+ {filteredData.map((pod: PodData) => ( +
+
+ Class ID: {pod.labels.class_id} +
+
+ Student ID: {pod.labels.student_id} +
+
+ Type: {pod.labels.vscode === "yes" ? "vscode" : ""} + {pod.labels.ssh === "yes" ? "SSH" : ""} +
+
+ Timestamp:{" "} + {new Date(pod.creationTimestamp).toLocaleString()} +
+
+ Status:{" "} + +
+
+ ))} +
+ ); +}; + +export default GridComponent; diff --git a/src/components/check/PodTable.module.css b/src/components/check/PodTable.module.css new file mode 100644 index 0000000..29d8f8b --- /dev/null +++ b/src/components/check/PodTable.module.css @@ -0,0 +1,58 @@ +.tableContainer { + width: 100%; + overflow-x: auto; +} + +.table { + width: 100%; + border-collapse: separate; + border-spacing: 0; + margin: 0 auto; + max-width: 100%; +} + +.table th, +.table td { + border: 1px solid var(--orange-color); + padding: 12px; + text-align: center; + font-size: 16px; +} + +.table th { + background-color: var(--orange50-color); + font-weight: bold; + color: #333; +} + +.statusRunning { + display: inline-block; + width: 12px; + height: 12px; + background-color: green; + border-radius: 50%; +} + +.statusNotRunning { + display: inline-block; + width: 12px; + height: 12px; + background-color: red; + border-radius: 50%; +} + +.table tr:first-child th:last-child { + border-top-right-radius: 12px; +} + +.table tr:last-child td:last-child { + border-bottom-right-radius: 12px; +} + +.table tr:first-child th:first-child { + border-top-left-radius: 12px; +} + +.table tr:last-child td:first-child { + border-bottom-left-radius: 12px; +} diff --git a/src/components/check/PodTable.tsx b/src/components/check/PodTable.tsx new file mode 100644 index 0000000..872cd3d --- /dev/null +++ b/src/components/check/PodTable.tsx @@ -0,0 +1,64 @@ +import React from "react"; +import styles from "./PodTable.module.css"; + +interface PodData { + name: string; + ip: string; + labels: { + app: string; + class_id: string; + pod_template_hash: string; + professor_id: string; + student_id: string; + vscode: string; + ssh: string; + }; + creationTimestamp: string; + status: string; +} + +interface PodTableProps { + filteredData: PodData[]; +} + +const PodTable = ({ filteredData }: PodTableProps) => { + return ( +
+ + + + + + + + + + + + {filteredData.map((pod) => ( + + + + + + + + ))} + +
Class IDStudent IDTypeTimestampStatus
{pod.labels.class_id}{pod.labels.student_id} + {pod.labels.vscode === "yes" ? "vscode" : ""} + {pod.labels.ssh === "yes" ? "SSH" : ""} + {new Date(pod.creationTimestamp).toLocaleString()} + +
+
+ ); +}; + +export default PodTable; diff --git a/src/components/common/ToggleButton.module.css b/src/components/common/ToggleButton.module.css new file mode 100644 index 0000000..6d15ce3 --- /dev/null +++ b/src/components/common/ToggleButton.module.css @@ -0,0 +1,70 @@ +.toggleButtonContainer { + display: flex; + justify-content: center; + align-items: center; +} + +.toggleButton { + position: relative; + display: flex; + align-items: center; + width: 80px; + height: 35px; + background-color: #f6f6f6; + border: none; + cursor: pointer; + border-radius: 50px; + padding: 5px 5px; + transition: background-color 0.3s; +} + +.toggleButton svg { + transition: transform 0.3s; + height: 30px; + width: 30px; +} + +.darkMode { + background-color: var(--lightgray-color); +} + +.moonIcon, +.sunIcon { + position: absolute; + transition: opacity 0.3s, transform 0.3s; +} + +.moonIcon { + left: 5px; + opacity: 0; +} + +.sunIcon { + right: 5px; + opacity: 1; +} + +.toggleButton.darkMode .moonIcon { + opacity: 1; +} + +.toggleButton.darkMode .sunIcon { + opacity: 0; +} + +.toggleButton::before { + content: ""; + position: absolute; + top: 50%; + left: 17.5px; + transform: translate(-50%, -50%); + width: 35px; + height: 35px; + background-color: var(--orange-color); + border-radius: 50%; + transition: transform 0.3s; +} + +.toggleButton.darkMode::before { + transform: translateX(35px) translate(-20%, -50%); +} diff --git a/src/components/common/ToggleButton.tsx b/src/components/common/ToggleButton.tsx new file mode 100644 index 0000000..26da733 --- /dev/null +++ b/src/components/common/ToggleButton.tsx @@ -0,0 +1,34 @@ +// ToggleButton.js +import React from "react"; +import SunIcon from "/public/icons/Sun.svg"; +import MoonIcon from "/public/icons/Moon.svg"; +import styles from "./ToggleButton.module.css"; + +interface ToggleButtonProps { + darkMode: boolean; + toggleDarkMode: () => void; +} + +const ToggleButton = ({ darkMode, toggleDarkMode }: ToggleButtonProps) => { + return ( +
+ +
+ ); +}; + +export default ToggleButton; diff --git a/src/components/common/WarningModal.module.css b/src/components/common/WarningModal.module.css new file mode 100644 index 0000000..022a506 --- /dev/null +++ b/src/components/common/WarningModal.module.css @@ -0,0 +1,45 @@ +.modalOverlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; +} + +.modal { + background: var(--orange-color); + padding: 25px; + border-radius: 12px; + max-width: 450px; + width: 100%; +} + +.modalContent { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + font-size: 20px; + font-family: "pretendard-bold"; +} + +.closeButton { + margin-top: 30px; + padding: 8px 20px; + background: var(--white-color); + color: var(--orange-color); + border: none; + border-radius: 4px; + cursor: pointer; +} + +@media (max-width: 768px) { + .modal { + max-width: 300px; + } +} diff --git a/src/components/common/WarningModal.tsx b/src/components/common/WarningModal.tsx new file mode 100644 index 0000000..2371eeb --- /dev/null +++ b/src/components/common/WarningModal.tsx @@ -0,0 +1,27 @@ +// components/Modal.js +import React from "react"; +import styles from "./WarningModal.module.css"; + +interface WarningModalProps { + message: string; + onClose: () => void; +} + +const WarningModal = ({ message, onClose }: WarningModalProps) => { + return ( + <> +
+
+
+

{message}

+ +
+
+
+ + ); +}; + +export default WarningModal; diff --git a/src/components/container/Container.module.css b/src/components/container/Container.module.css new file mode 100644 index 0000000..575a8cd --- /dev/null +++ b/src/components/container/Container.module.css @@ -0,0 +1,60 @@ +.container { + min-width: 300px; + height: 240px; + background-color: var(--lightgray2-color); + border-radius: 10px; +} + +.container:hover { + transform: scale(1.03); + box-shadow: 0 0 10px 0 rgb(240, 162, 54); + transition: transform 0.3s ease; +} + +.topContainer { + height: 120px; + background-color: var(--orange-color); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + border-radius: 10px 10px 0 0; +} + +.bottomContainer { + height: 120px; + display: flex; + padding: 10px; + flex-direction: column; + gap: 5px; + color: var(--black-color); +} +.topDescription { + color: var(--green-color); + display: flex; + flex-direction: row; + gap: 5px; + font-family: "Pretendard-bold"; +} +.bottomDescription { + padding-top: 20px; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; +} +.icon { + fill: var(--gray-color); +} + +.icon:hover { + fill: var(--orange-color); + cursor: pointer; + transition: fill 0.15s ease; +} + +@media (max-width: 480px) { + .container { + width: 300px; + } +} diff --git a/src/components/container/Container.tsx b/src/components/container/Container.tsx new file mode 100644 index 0000000..d81f013 --- /dev/null +++ b/src/components/container/Container.tsx @@ -0,0 +1,72 @@ +// Container.tsx +import React, { useState } from "react"; +import styles from "./Container.module.css"; +import VSCodeIcon from "/public/icons/VSCode.svg"; +import SSHIcon from "/public/icons/SSH.svg"; +import PlayIcon from "/public/icons/Play.svg"; +import SSHModal from "./SSHModal"; + +interface ContainerProps { + type: string; + port_number?: number | null; + ssh_commands?: string[] | null; + course_name: string; + professor_name: string; + semester: string; + language: string; +} + +export default function Container({ + type, + port_number, + ssh_commands, + course_name, + professor_name, + semester, + language, +}: ContainerProps) { + const [isModalOpen, setModalOpen] = useState(false); + + const icon = type === "vscode" ? : ; + const temp_port = 37001; + + const handlePlayClick = () => { + if (type === "vscode") { + const url = `${process.env.NEXT_PUBLIC_CONTAINER_URL}:${temp_port}`; + window.open(url, "_blank"); + } else { + setModalOpen(true); + } + }; + + return ( + <> +
+
{icon}
+
+
+
{course_name}
+
({professor_name})
+
+
{semester}
+
+
Language: {language}
+ +
+
+
+ {ssh_commands && ( + setModalOpen(false)} + content={ssh_commands} + /> + )} + + ); +} diff --git a/src/components/container/Filter.module.css b/src/components/container/Filter.module.css new file mode 100644 index 0000000..ad3e0c0 --- /dev/null +++ b/src/components/container/Filter.module.css @@ -0,0 +1,49 @@ +.filter { + width: 180px; + position: relative; /* 부모 요소를 relative로 설정 */ +} + +.filterButton { + width: 100%; + height: 50px; + display: flex; + background-color: var(--gray-color); + border-radius: 10px; + padding: 10px; + align-items: center; + justify-content: space-between; + gap: 10px; +} + +.icon { + cursor: pointer; + padding: 5px; +} + +.filterOptions { + color: var(--white-color); + display: flex; + flex-direction: column; + position: absolute; + top: 40px; + right: 0; + width: 100%; + background-color: var(--gray-color); + border-bottom-left-radius: 10px; + border-bottom-right-radius: 10px; + padding: 0px 10px; + overflow: hidden; + max-height: 0; + gap: 10px; + transition: max-height 0.3s ease-out, 0.3s ease-out; + z-index: 1; + cursor: pointer; +} +.filterOptions div:hover { + color: var(--orange-color); +} + +.filterOptions.open { + padding: 20px 10px 15px 10px; + max-height: 200px; +} diff --git a/src/components/container/Filter.tsx b/src/components/container/Filter.tsx new file mode 100644 index 0000000..ba7b3a6 --- /dev/null +++ b/src/components/container/Filter.tsx @@ -0,0 +1,61 @@ +"use client"; + +import { useState } from "react"; +import { useRouter } from "next/navigation"; +import FilterIcon from "/public/icons/Filter.svg"; +import DownIcon from "/public/icons/Down.svg"; +import UpIcon from "/public/icons/Up.svg"; +import styles from "./Filter.module.css"; + +interface FilterProps { + onSelect: (option: string) => void; +} + +export default function Filter({ onSelect }: FilterProps) { + const [isFilterOpen, setFilterOpen] = useState(false); + const router = useRouter(); + + const toggleFilter = () => { + setFilterOpen(!isFilterOpen); + }; + + const handleSelect = (option: string) => { + onSelect(option); + setFilterOpen(false); + switch (option) { + case "전체 학기": + router.push("/container/all"); + break; + case "최근 실행": + router.push("/container/recent"); + break; + case "이번 학기": + router.push("/container/semester"); + break; + default: + break; + } + }; + + return ( +
+
+ +
+ {isFilterOpen ? ( + + ) : ( + + )} +
+
+
+
handleSelect("전체 학기")}>전체 학기
+
handleSelect("최근 실행")}>최근 실행
+
handleSelect("이번 학기")}>이번 학기
+
+
+ ); +} diff --git a/src/components/container/SSHModal.module.css b/src/components/container/SSHModal.module.css new file mode 100644 index 0000000..d1bfdc7 --- /dev/null +++ b/src/components/container/SSHModal.module.css @@ -0,0 +1,55 @@ +.overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; +} + +.modal { + background-color: var(--orange-color); + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + gap: 20px; + padding: 20px; + width: 400px; + border-radius: 12px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + color: var(--gray-color); +} + +.header { + text-align: center; + font-size: 24px; + font-family: "Pretendard-bold"; + color: var(--gray-color); +} + +.content { + display: flex; + flex-direction: column; + gap: 5px; + font-family: "Pretendard-bold"; + color: var(--gray-color); +} + +.button { + background-color: var(--white-color); + border-radius: 8px; + color: var(--orange-color); + padding: 10px 20px; + border: none; + cursor: pointer; +} + +@media (max-width: 480px) { + .modal { + width: 90%; + } +} diff --git a/src/components/container/SSHModal.tsx b/src/components/container/SSHModal.tsx new file mode 100644 index 0000000..2b7e824 --- /dev/null +++ b/src/components/container/SSHModal.tsx @@ -0,0 +1,32 @@ +import React from "react"; +import styles from "./SSHModal.module.css"; + +interface ModalProps { + isOpen: boolean; + onClose: () => void; + content: string[]; +} + +const Modal = ({ isOpen, onClose, content }: ModalProps) => { + if (!isOpen) return null; + + return ( +
+
+
+ 아래 SSH 명령어를
순차적으로 입력하세요 +
+
+ {content.map((cmd, index) => ( +

{cmd}

+ ))} +
+ +
+
+ ); +}; + +export default Modal; diff --git a/src/components/help/HelpFilter.module.css b/src/components/help/HelpFilter.module.css new file mode 100644 index 0000000..6bb2562 --- /dev/null +++ b/src/components/help/HelpFilter.module.css @@ -0,0 +1,17 @@ +.filter { + display: flex; + gap: 10px; + margin-bottom: 20px; +} + +.button { + padding: 10px 20px; + border-radius: 8px; + cursor: pointer; +} + +.button.active { + background-color: var(--orange-color); + color: #fff; + border: none; +} diff --git a/src/components/help/HelpFilter.tsx b/src/components/help/HelpFilter.tsx new file mode 100644 index 0000000..4530525 --- /dev/null +++ b/src/components/help/HelpFilter.tsx @@ -0,0 +1,32 @@ +import React from "react"; +import styles from "./HelpFilter.module.css"; + +interface FilterProps { + onViewChange: (view: string) => void; + currentView: string; +} + +const HelpFilter = ({ onViewChange, currentView }: FilterProps) => { + return ( +
+ + +
+ ); +}; + +export default HelpFilter; diff --git a/src/components/help/HelpItem.module.css b/src/components/help/HelpItem.module.css new file mode 100644 index 0000000..d3f23b0 --- /dev/null +++ b/src/components/help/HelpItem.module.css @@ -0,0 +1,23 @@ +.helpItem { + border: 1px solid var(--orange-color); + padding: 15px; + border-radius: 8px; +} + +.title { + font-size: 20px; + font-weight: bold; + color: var(--orange-color); +} + +.body { + font-size: 16px; + margin-top: 10px; +} + +.category { + display: block; + margin-top: 15px; + font-size: 14px; + color: #777; +} diff --git a/src/components/help/HelpItem.tsx b/src/components/help/HelpItem.tsx new file mode 100644 index 0000000..934f93c --- /dev/null +++ b/src/components/help/HelpItem.tsx @@ -0,0 +1,20 @@ +import React from "react"; +import styles from "./HelpItem.module.css"; + +interface HelpItemProps { + title: string; + body: string; + category: string; +} + +const HelpItem = ({ title, body, category }: HelpItemProps) => { + return ( +
+

{title}

+

{body}

+ {category} +
+ ); +}; + +export default HelpItem; diff --git a/src/components/notice/FilterNotice.module.css b/src/components/notice/FilterNotice.module.css new file mode 100644 index 0000000..c8013d0 --- /dev/null +++ b/src/components/notice/FilterNotice.module.css @@ -0,0 +1,77 @@ +.filter { + width: 180px; + position: relative; +} + +.filterButton { + width: 100%; + height: 50px; + display: flex; + background-color: var(--gray-color); + border-radius: 10px; + padding: 10px; + align-items: center; + justify-content: space-between; + gap: 10px; +} + +.icon { + cursor: pointer; + padding: 5px; +} + +.filterOptions { + color: var(--white-color); + display: flex; + flex-direction: column; + position: absolute; + top: 40px; + right: 0; + width: 100%; + background-color: var(--gray-color); + border-bottom-left-radius: 10px; + border-bottom-right-radius: 10px; + padding: 0px 10px; + overflow: hidden; + max-height: 0; + gap: 10px; + transition: max-height 0.3s ease-out, padding 0.3s ease-out; + z-index: 1; + cursor: pointer; +} + +.filterOptions div:hover { + color: var(--orange-color); +} + +.filterOptions.open { + padding: 20px 10px 15px 10px; + max-height: 200px; +} + +.smallScreen { + display: none; +} +.filterSmall { + display: flex; + gap: 20px; +} +.filterButtonSmall { + background-color: var(--orange50-color); + padding: 10px 15px; + border-radius: 10px; + cursor: pointer; +} + +@media (max-width: 768px) { + .filter { + display: none; + } + .smallScreen { + display: block; + justify-content: space-between; + align-items: center; + gap: 10px; + color: var(--white-color); + } +} diff --git a/src/components/notice/FilterNotice.tsx b/src/components/notice/FilterNotice.tsx new file mode 100644 index 0000000..d3af903 --- /dev/null +++ b/src/components/notice/FilterNotice.tsx @@ -0,0 +1,81 @@ +"use client"; + +import { useState } from "react"; +import { useRouter } from "next/navigation"; +import FilterIcon from "/public/icons/Filter.svg"; +import DownIcon from "/public/icons/Down.svg"; +import UpIcon from "/public/icons/Up.svg"; +import styles from "./FilterNotice.module.css"; + +interface FilterProps { + onSelect: (option: string) => void; +} + +export default function Filter({ onSelect }: FilterProps) { + const [isFilterOpen, setFilterOpen] = useState(false); + const router = useRouter(); + + const toggleFilter = () => { + setFilterOpen(!isFilterOpen); + }; + + const handleSelect = (option: string) => { + onSelect(option); + setFilterOpen(false); + switch (option) { + case "전체 과목 공지 보기": + router.push("/notice/all"); + break; + case "과목별 공지 보기": + router.push("/notice/specific"); + break; + default: + break; + } + }; + + return ( + <> +
+
+ +
+ {isFilterOpen ? ( + + ) : ( + + )} +
+
+
+
handleSelect("전체 과목 공지 보기")}> + 전체 과목 공지 보기 +
+
handleSelect("과목별 공지 보기")}> + 과목별 공지 보기 +
+
+
+
+
+
handleSelect("전체 과목 공지 보기")} + className={styles.filterButtonSmall} + > + 전체 과목 공지 보기 +
+
handleSelect("과목별 공지 보기")} + className={styles.filterButtonSmall} + > + 과목별 공지 보기 +
+
+
+ + ); +} diff --git a/src/components/notice/NoticeItem.module.css b/src/components/notice/NoticeItem.module.css new file mode 100644 index 0000000..bd9cd9e --- /dev/null +++ b/src/components/notice/NoticeItem.module.css @@ -0,0 +1,109 @@ +.noticeItem { + border-bottom: 1px solid var(--white-color); + padding: 15px 15px 20px 10px; + cursor: pointer; +} + +.noticeTitle { + font-family: "Pretendard-bold"; + margin-bottom: 10px; +} + +.noticeHeader { + font-size: 20px; + font-family: "Pretendard-bold"; + padding-bottom: 20px; +} + +.noticeBody { + font-size: 16px; + margin-bottom: 10px; + color: var(--white-color); + overflow-wrap: break-word; +} + +.noticeFooter { + display: flex; + gap: 10px; + font-size: 14px; + color: #777; +} + +.courseName { + font-family: "Pretendard-bold"; + color: var(--orange-color); +} + +.professorName { + font-style: italic; + color: var(--orange-color); + font-size: 18px; +} + +.postDate { + margin-left: auto; + + white-space: nowrap; +} + +/* 반응형 디자인 */ +@media (max-width: 768px) { + .noticeHeader { + font-size: 18px; + padding-bottom: 15px; + } + + .noticeTitle { + font-size: 18px; + margin-bottom: 8px; + } + + .noticeBody { + font-size: 14px; + margin-bottom: 8px; + overflow-wrap: break-word; + } + + .noticeFooter { + flex-direction: column; + align-items: flex-start; + gap: 5px; + } + + .postDate { + margin-left: 0; + font-size: 12px; + } +} + +@media (max-width: 480px) { + .noticeItem { + width: 320px; + padding: 10px 5px 15px 5px; + } + .noticeHeader { + font-size: 16px; + padding-bottom: 10px; + } + + .noticeTitle { + font-size: 16px; + margin-bottom: 6px; + } + + .noticeBody { + font-size: 12px; + margin-bottom: 6px; + overflow-wrap: break-word; + } + + .noticeFooter { + font-size: 12px; + align-items: flex-start; + gap: 5px; + } + + .postDate { + font-size: 12px; + } +} diff --git a/src/components/notice/NoticeItem.tsx b/src/components/notice/NoticeItem.tsx new file mode 100644 index 0000000..c0980cd --- /dev/null +++ b/src/components/notice/NoticeItem.tsx @@ -0,0 +1,56 @@ +import React, { useState } from "react"; +import styles from "./NoticeItem.module.css"; +import NoticeModal from "@/components/notice/NoticeModal"; + +interface NoticeItemProps { + notice_title: string; + notice_body: string; + course_name: string; + professor_name: string; + post_date: string; +} + +const NoticeItem = ({ + notice_title, + notice_body, + course_name, + professor_name, + post_date, +}: NoticeItemProps) => { + const [showModal, setShowModal] = useState(false); + + const handleOpenModal = () => { + setShowModal(true); + }; + + const handleCloseModal = () => { + setShowModal(false); + }; + + return ( + <> +
+
+ {course_name} + ({professor_name}) +
+
{notice_title}
+
+

{notice_body}

+ 게시일시: {post_date} +
+
+ + + ); +}; + +export default NoticeItem; diff --git a/src/components/notice/NoticeModal.module.css b/src/components/notice/NoticeModal.module.css new file mode 100644 index 0000000..eb407eb --- /dev/null +++ b/src/components/notice/NoticeModal.module.css @@ -0,0 +1,39 @@ +.modalOverlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; +} + +.modalContent { + background-color: var(--orange-color); + padding: 20px; + border-radius: 8px; + width: 80%; + max-width: 600px; +} + +.modalHeader { + display: flex; + justify-content: space-between; + align-items: center; +} + +.closeButton { + background: none; + border: none; + font-size: 1.5rem; + cursor: pointer; + color: var(--white-color); + padding: 5px; +} + +.modalBody { + margin-top: 10px; +} diff --git a/src/components/notice/NoticeModal.tsx b/src/components/notice/NoticeModal.tsx new file mode 100644 index 0000000..6b20364 --- /dev/null +++ b/src/components/notice/NoticeModal.tsx @@ -0,0 +1,53 @@ +import React from "react"; +import styles from "./NoticeModal.module.css"; + +interface ModalProps { + show: boolean; + onClose: () => void; + title: string; + courseName: string; + professorName: string; + postDate: string; + noticeBody: string; +} + +const Modal = ({ + show, + onClose, + title, + courseName, + professorName, + postDate, + noticeBody, +}: ModalProps) => { + if (!show) return null; + + return ( +
+
+
+

{title}

+ +
+
+

+ Course: {courseName} +

+

+ Professor: {professorName} +

+

+ Date: {postDate} +

+

+ notice: {noticeBody} +

+
+
+
+ ); +}; + +export default Modal; diff --git a/src/components/onboarding/TopNavBar.module.css b/src/components/onboarding/TopNavBar.module.css new file mode 100644 index 0000000..23ffce2 --- /dev/null +++ b/src/components/onboarding/TopNavBar.module.css @@ -0,0 +1,43 @@ +.topNavBar { + display: flex; + justify-content: space-between; + align-items: center; + + padding: 10px 50px; + border: 1px solid var(--lightgray-color); + border-radius: 50px; + margin: 40px 100px 0; +} +.navLeft { + display: flex; + align-items: center; + gap: 24px; +} +.logoText { + font-size: 18px; + text-decoration: none; + font-family: "Pretendard-Medium"; + color: var(--white-color); +} + +.logoText:hover { + cursor: pointer; + color: var(--orange-color); +} + +@media (max-width: 800px) { + .topNavBar { + margin: 40px 20px; + padding: 10px 20px; + } +} + +@media (max-width: 600px) { + .topNavBar { + flex-direction: column; + gap: 20px; + } + .logoText { + font-size: 16px; + } +} diff --git a/src/components/onboarding/TopNavBar.tsx b/src/components/onboarding/TopNavBar.tsx new file mode 100644 index 0000000..4c24408 --- /dev/null +++ b/src/components/onboarding/TopNavBar.tsx @@ -0,0 +1,22 @@ +import React from "react"; +import styles from "./TopNavBar.module.css"; +import LogoRowIcon from "/public/icons/LogoRow.svg"; +import Link from "next/link"; + +export default function page() { + return ( +
+ +
+
도움말
+
릴리즈 노트
+ +
로그인
+ + +
회원가입
+ +
+
+ ); +} diff --git a/src/data/dummy_check_data.json b/src/data/dummy_check_data.json new file mode 100644 index 0000000..144ce7c --- /dev/null +++ b/src/data/dummy_check_data.json @@ -0,0 +1,137 @@ +[ + { + "name": "id-2019312219-java2024-764bf8659c-lzgtd", + "ip": "10.42.0.92", + "labels": { + "app": "id-2019312219-java2024", + "class_id": "id-java2024", + "pod_template_hash": "764bf8659c", + "professor_id": "id-2019312218", + "student_id": "id-2019312219", + "vscode": "yes", + "ssh": "no" + }, + "creationTimestamp": "2024-05-30T07:52:59Z", + "status": "Running" + }, + { + "name": "id-2019312433-java2024-549bfc5445-z658v", + "ip": "10.42.0.93", + "labels": { + "app": "id-2019312433-java2024", + "class_id": "id-java2024", + "pod_template_hash": "764bf8659c", + "professor_id": "id-2019312218", + "student_id": "id-2019312433", + "vscode": "yes", + "ssh": "no" + }, + "creationTimestamp": "2024-05-30T07:53:00Z", + "status": "Error" + }, + { + "name": "id-2019312557-java2024-34fbc6545d-h567v", + "ip": "10.42.0.94", + "labels": { + "app": "id-2019312557-java2024", + "class_id": "id-java2024", + "pod_template_hash": "764bf8659c", + "professor_id": "id-2019312218", + "student_id": "id-2019312557", + "vscode": "yes", + "ssh": "no" + }, + "creationTimestamp": "2024-05-30T07:53:01Z", + "status": "Running" + }, + { + "name": "id-2019321678-python2024-78bfa6546d-k912x", + "ip": "10.42.0.95", + "labels": { + "app": "id-2019321678-python2024", + "class_id": "id-python2024", + "pod_template_hash": "764bf8659c", + "professor_id": "id-2019321677", + "student_id": "id-2019321678", + "vscode": "yes", + "ssh": "no" + }, + "creationTimestamp": "2024-05-30T08:00:00Z", + "status": "Running" + }, + { + "name": "id-2019321890-python2024-12fdc8765a-m357y", + "ip": "10.42.0.96", + "labels": { + "app": "id-2019321890-python2024", + "class_id": "id-python2024", + "pod_template_hash": "764bf8659c", + "professor_id": "id-2019321677", + "student_id": "id-2019321890", + "vscode": "no", + "ssh": "yes" + }, + "creationTimestamp": "2024-05-30T08:00:01Z", + "status": "Running" + }, + { + "name": "id-2019321456-python2024-45baf6546d-r568u", + "ip": "10.42.0.97", + "labels": { + "app": "id-2019321456-python2024", + "class_id": "id-python2024", + "pod_template_hash": "764bf8659c", + "professor_id": "id-2019321677", + "student_id": "id-2019321456", + "vscode": "yes", + "ssh": "no" + }, + "creationTimestamp": "2024-05-30T08:00:02Z", + "status": "Running" + }, + { + "name": "id-2019331789-cpp2024-98bfa7654e-h921z", + "ip": "10.42.0.98", + "labels": { + "app": "id-2019331789-cpp2024", + "class_id": "id-cpp2024", + "pod_template_hash": "764bf8659c", + "professor_id": "id-2019331788", + "student_id": "id-2019331789", + "vscode": "yes", + "ssh": "no" + }, + "creationTimestamp": "2024-05-30T08:05:00Z", + "status": "Error" + }, + { + "name": "id-2019331992-cpp2024-67cda9876b-k348v", + "ip": "10.42.0.99", + "labels": { + "app": "id-2019331992-cpp2024", + "class_id": "id-cpp2024", + "pod_template_hash": "764bf8659c", + "professor_id": "id-2019331788", + "student_id": "id-2019331992", + "vscode": "no", + "ssh": "yes" + }, + "creationTimestamp": "2024-05-30T08:05:01Z", + "status": "Running" + }, + { + "name": "id-2019331564-cpp2024-34baf7654d-l786y", + "ip": "10.42.0.100", + "labels": { + "app": "id-2019331564-cpp2024", + "class_id": "id-cpp2024", + "pod_template_hash": "764bf8659c", + "professor_id": "id-2019331788", + "student_id": "id-2019331564", + "vscode": "yes", + "ssh": "no" + }, + "creationTimestamp": "2024-05-30T08:05:02Z", + "status": "Running" + } +] diff --git a/src/data/dummy_container_data.json b/src/data/dummy_container_data.json new file mode 100644 index 0000000..7e3f135 --- /dev/null +++ b/src/data/dummy_container_data.json @@ -0,0 +1,66 @@ +[ + { + "type": "vscode", + "port_number": 8080, + "ssh_commands": null, + "course_name": "Advanced Algorithms", + "professor_name": "Dr. Smith", + "semester": "Fall 2023", + "language": "C++" + }, + { + "type": "ssh", + "port_number": null, + "ssh_commands": [ + "ssh user@192.168.1.1", + "ssh -p 2222 user@192.168.1.2", + "ssh -i ~/.ssh/id_rsa user@192.168.1.3" + ], + "course_name": "Machine Learning", + "professor_name": "Dr. Johnson", + "semester": "Spring 2024", + "language": "Python" + }, + { + "type": "vscode", + "port_number": 3000, + "ssh_commands": null, + "course_name": "Data Structures", + "professor_name": "Dr. Williams", + "semester": "Spring 2024", + "language": "Java" + }, + { + "type": "ssh", + "port_number": null, + "ssh_commands": [ + "ssh -L 8080:localhost:8080 user@192.168.1.4", + "ssh -R 9090:localhost:9090 user@192.168.1.5" + ], + "course_name": "Operating Systems", + "professor_name": "Dr. Brown", + "semester": "Spring 2024", + "language": "C" + }, + { + "type": "vscode", + "port_number": 5000, + "ssh_commands": null, + "course_name": "Computer Networks", + "professor_name": "Dr. Davis", + "semester": "Fall 2023", + "language": "Go" + }, + { + "type": "ssh", + "port_number": null, + "ssh_commands": [ + "ssh -L 3306:localhost:3306 user@192.168.1.6", + "ssh -R 5432:localhost:5432 user@192.168.1.7" + ], + "course_name": "Database Systems", + "professor_name": "Dr. Miller", + "semester": "Spring 2023", + "language": "SQL" + } +] diff --git a/src/data/dummy_edit_data.json b/src/data/dummy_edit_data.json new file mode 100644 index 0000000..7699627 --- /dev/null +++ b/src/data/dummy_edit_data.json @@ -0,0 +1,20 @@ +[ + { + "id": "id-java2024", + "type": "vscode", + "port": "8080", + "command": "" + }, + { + "id": "id-python2024", + "type": "ssh", + "port": "", + "command": "ssh -p 22 user@host" + }, + { + "id": "id-cpp2024", + "type": "vscode", + "port": "9090", + "command": "" + } +] diff --git a/src/data/dummy_help_data.json b/src/data/dummy_help_data.json new file mode 100644 index 0000000..69c8b76 --- /dev/null +++ b/src/data/dummy_help_data.json @@ -0,0 +1,68 @@ +[ + { + "id": 1, + "title": "How to login", + "body": "Instructions on how to login to the system.", + "category": "General" + }, + { + "id": 2, + "title": "Reset Password", + "body": "Steps to reset your password.", + "category": "Account" + }, + { + "id": 3, + "title": "Navigating the Dashboard", + "body": "Guide to navigate through the dashboard.", + "category": "General" + }, + { + "id": 4, + "title": "Setting up Two-Factor Authentication", + "body": "How to set up two-factor authentication.", + "category": "Security" + }, + { + "id": 5, + "title": "Updating Profile Information", + "body": "Steps to update your profile information.", + "category": "Account" + }, + { + "id": 6, + "title": "Managing Notifications", + "body": "How to manage notification settings.", + "category": "General" + }, + { + "id": 7, + "title": "Creating a New Account", + "body": "Instructions on how to create a new account.", + "category": "Account" + }, + { + "id": 8, + "title": "Privacy Settings", + "body": "Guide to adjust your privacy settings.", + "category": "Security" + }, + { + "id": 9, + "title": "Using the Help Center", + "body": "How to use the help center to find answers.", + "category": "General" + }, + { + "id": 10, + "title": "Deleting Your Account", + "body": "Steps to delete your account permanently.", + "category": "Account" + }, + { + "id": 11, + "title": "Reporting a Bug", + "body": "How to report a bug or issue in the system.", + "category": "General" + } +] diff --git a/src/data/dummy_message_data.json b/src/data/dummy_message_data.json new file mode 100644 index 0000000..8e27621 --- /dev/null +++ b/src/data/dummy_message_data.json @@ -0,0 +1,45 @@ +[ + { + "id": 1, + "sender": "You", + "text": "Hello, Professor!", + "timestamp": "2023-12-01 10:00:00" + }, + { + "id": 2, + "sender": "Professor", + "text": "Hello, how can I help you?", + "timestamp": "2023-12-01 10:01:00" + }, + { + "id": 3, + "sender": "You", + "text": "Could you explain the assignment?", + "timestamp": "2023-12-01 10:05:00" + }, + { + "id": 4, + "sender": "Professor", + "text": "Sure, the assignment is about ...", + "timestamp": "2023-12-01 10:10:00" + }, + + { + "id": 5, + "sender": "Professor", + "text": "Sure, the assignment is about ...", + "timestamp": "2023-12-01 10:10:00" + }, + { + "id": 6, + "sender": "You", + "text": "Sure, the assignment is about ...", + "timestamp": "2023-12-01 10:10:00" + }, + { + "id": 7, + "sender": "Professor", + "text": "Sure, the assignment is about ...", + "timestamp": "2023-12-01 10:10:00" + } +] diff --git a/src/data/dummy_notice_data.json b/src/data/dummy_notice_data.json new file mode 100644 index 0000000..c91d21e --- /dev/null +++ b/src/data/dummy_notice_data.json @@ -0,0 +1,44 @@ +[ + { + "course_name": "Advanced Algorithms", + "professor_name": "Dr. Smith", + "notice_title": "Assignment 1 Released", + "notice_body": "Please check the course website for the details of Assignment 1.", + "post_date": "2024-01-15" + }, + { + "course_name": "Machine Learning", + "professor_name": "Dr. Johnson", + "notice_title": "Project Proposal Submission", + "notice_body": "The deadline for project proposal submission is next Monday.", + "post_date": "2024-02-10" + }, + { + "course_name": "Data Structures", + "professor_name": "Dr. Williams", + "notice_title": "Midterm Exam Schedule", + "notice_body": "The midterm exam will be held on March 20th during class hours.", + "post_date": "2024-03-05" + }, + { + "course_name": "Machine Learning", + "professor_name": "Dr. Johnson", + "notice_title": "Lab 3 Instructions", + "notice_body": "Lab 3 instructions have been posted. Please complete it by the end of this week.", + "post_date": "2024-03-18" + }, + { + "course_name": "Machine Learning", + "professor_name": "Dr. Johnson", + "notice_title": "Final Exam Topics", + "notice_body": "The final exam will cover chapters 1 to 10.", + "post_date": "2024-04-22" + }, + { + "course_name": "Database Systems", + "professor_name": "Dr. Miller", + "notice_title": "Homework 2 Due Date", + "notice_body": "Homework 2 is due on May 5th. Please submit it via the course portal.", + "post_date": "2024-05-01" + } +] diff --git a/src/store/authStore.tsx b/src/store/authStore.tsx new file mode 100644 index 0000000..95be85d --- /dev/null +++ b/src/store/authStore.tsx @@ -0,0 +1,69 @@ +import { create } from "zustand"; +import { createJSONStorage, persist } from "zustand/middleware"; + +// 유저 정보 추가 +interface User { + name: string; + studentId: string; + email: string; + isStudent: boolean; +} + +interface AuthState { + user: User | null; + isLoggedIn: boolean; + isLoading: boolean; + login: (user: User) => void; + logout: () => void; + setLoading: (loading: boolean) => void; +} + +const userDummyStudent = { + name: "김태건", + studentId: "2019312430", + email: "aksen5240@gmail.com", + isStudent: true, +}; + +const userDummyProfessor = { + name: "교수자1", + studentId: "1999312430", + email: "aksen5240@gmail.com", + isStudent: false, +}; + +export const useAuthStore = create()( + persist( + (set) => ({ + user: null, + isLoggedIn: false, + isLoading: true, + login: (user: User) => { + set({ user: user, isLoggedIn: true, isLoading: false }); + sessionStorage.setItem("isLoggedIn", "true"); + }, + logout: () => { + set({ user: null, isLoggedIn: false, isLoading: false }); + sessionStorage.removeItem("isLoggedIn"); + }, + setLoading: (loading: boolean) => set({ isLoading: loading }), + }), + { + name: "authStore", + storage: createJSONStorage(() => sessionStorage), + onRehydrateStorage: () => (state) => { + state?.setLoading(false); + }, + } + ) +); + +export const authenticateUser = (email: string, password: string) => { + if (email === "student" && password === "123") { + return userDummyStudent; + } else if (email === "professor" && password === "123") { + return userDummyProfessor; + } else { + return null; + } +};