diff --git a/.gitignore b/.gitignore
index a547bf3..1ab3c71 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,9 @@ dist
dist-ssr
*.local
+# Environment variables
+.env
+
# Editor directories and files
.vscode/*
!.vscode/extensions.json
@@ -22,3 +25,5 @@ dist-ssr
*.njsproj
*.sln
*.sw?
+
+*storybook.log
diff --git a/.storybook/main.ts b/.storybook/main.ts
new file mode 100644
index 0000000..568ce2f
--- /dev/null
+++ b/.storybook/main.ts
@@ -0,0 +1,16 @@
+import type { StorybookConfig } from '@storybook/react-vite';
+
+const config: StorybookConfig = {
+ stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
+ addons: [
+ '@storybook/addon-onboarding',
+ '@storybook/addon-essentials',
+ '@chromatic-com/storybook',
+ '@storybook/addon-interactions',
+ ],
+ framework: {
+ name: '@storybook/react-vite',
+ options: {},
+ },
+};
+export default config;
diff --git a/.storybook/preview.ts b/.storybook/preview.ts
new file mode 100644
index 0000000..838f72d
--- /dev/null
+++ b/.storybook/preview.ts
@@ -0,0 +1,15 @@
+import type { Preview } from '@storybook/react';
+import '../src/styles/reset.css';
+
+const preview: Preview = {
+ parameters: {
+ controls: {
+ matchers: {
+ color: /(background|color)$/i,
+ date: /Date$/i,
+ },
+ },
+ },
+};
+
+export default preview;
diff --git a/index.html b/index.html
index e4b78ea..7457476 100644
--- a/index.html
+++ b/index.html
@@ -1,8 +1,9 @@
-
+
+
Vite + React + TS
diff --git a/package.json b/package.json
index 9c80792..771508d 100644
--- a/package.json
+++ b/package.json
@@ -8,28 +8,61 @@
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview",
- "prepare": "husky"
+ "prepare": "husky",
+ "storybook": "storybook dev -p 6006",
+ "build-storybook": "storybook build"
},
"dependencies": {
+ "@heroicons/react": "^2.2.0",
"@reduxjs/toolkit": "^2.4.0",
"@tanstack/react-query": "^5.62.2",
+ "@types/quill": "^2.0.14",
+ "@types/react-redux": "^7.1.34",
+ "axios": "^1.7.9",
+ "dompurify": "^3.2.3",
+ "jwt-decode": "^4.0.0",
+ "quill": "^2.0.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
+ "react-hook-form": "^7.54.1",
+ "react-quill": "^2.0.0",
"react-redux": "^9.1.2",
"react-router": "^7.0.2",
+ "redux-persist": "^6.0.0",
"styled-components": "^6.1.13"
},
"devDependencies": {
+ "@chromatic-com/storybook": "^3.2.2",
"@eslint/js": "^9.15.0",
- "@types/react": "^18.3.12",
- "@types/react-dom": "^18.3.1",
+ "@storybook/addon-essentials": "^8.4.7",
+ "@storybook/addon-interactions": "^8.4.7",
+ "@storybook/addon-onboarding": "^8.4.7",
+ "@storybook/blocks": "^8.4.7",
+ "@storybook/react": "^8.4.7",
+ "@storybook/react-vite": "^8.4.7",
+ "@storybook/test": "^8.4.7",
+ "@types/jwt-decode": "^3.1.0",
+ "@types/react": "^18.3.14",
+ "@types/react-dom": "^18.3.2",
+ "@types/redux-persist": "^4.3.1",
"@vitejs/plugin-react": "^4.3.4",
"eslint": "^9.15.0",
"eslint-plugin-react-hooks": "^5.0.0",
"eslint-plugin-react-refresh": "^0.4.14",
+ "eslint-plugin-storybook": "^0.11.1",
"globals": "^15.12.0",
+ "husky": "^9.1.7",
+ "msw": "^2.6.8",
+ "storybook": "^8.4.7",
"typescript": "~5.6.2",
"typescript-eslint": "^8.15.0",
- "vite": "^6.0.1"
+ "vite": "^6.0.3",
+ "vite-plugin-svgr": "^4.3.0",
+ "vitest": "^2.1.8"
+ },
+ "eslintConfig": {
+ "extends": [
+ "plugin:storybook/recommended"
+ ]
}
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 475f3a1..263b7b0 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -8,40 +8,100 @@ importers:
.:
dependencies:
+ '@heroicons/react':
+ specifier: ^2.2.0
+ version: 2.2.0(react@18.3.1)
'@reduxjs/toolkit':
specifier: ^2.4.0
version: 2.4.0(react-redux@9.1.2(@types/react@18.3.14)(react@18.3.1)(redux@5.0.1))(react@18.3.1)
'@tanstack/react-query':
specifier: ^5.62.2
version: 5.62.2(react@18.3.1)
+ '@types/quill':
+ specifier: ^2.0.14
+ version: 2.0.14
+ '@types/react-redux':
+ specifier: ^7.1.34
+ version: 7.1.34
+ axios:
+ specifier: ^1.7.9
+ version: 1.7.9
+ dompurify:
+ specifier: ^3.2.3
+ version: 3.2.3
+ jwt-decode:
+ specifier: ^4.0.0
+ version: 4.0.0
+ quill:
+ specifier: ^2.0.3
+ version: 2.0.3
react:
specifier: ^18.3.1
version: 18.3.1
react-dom:
specifier: ^18.3.1
version: 18.3.1(react@18.3.1)
+ react-hook-form:
+ specifier: ^7.54.1
+ version: 7.54.1(react@18.3.1)
+ react-quill:
+ specifier: ^2.0.0
+ version: 2.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react-redux:
specifier: ^9.1.2
version: 9.1.2(@types/react@18.3.14)(react@18.3.1)(redux@5.0.1)
react-router:
specifier: ^7.0.2
version: 7.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ redux-persist:
+ specifier: ^6.0.0
+ version: 6.0.0(react@18.3.1)(redux@5.0.1)
styled-components:
specifier: ^6.1.13
version: 6.1.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
devDependencies:
+ '@chromatic-com/storybook':
+ specifier: ^3.2.2
+ version: 3.2.2(react@18.3.1)(storybook@8.4.7)
'@eslint/js':
specifier: ^9.15.0
version: 9.16.0
+ '@storybook/addon-essentials':
+ specifier: ^8.4.7
+ version: 8.4.7(@types/react@18.3.14)(storybook@8.4.7)
+ '@storybook/addon-interactions':
+ specifier: ^8.4.7
+ version: 8.4.7(storybook@8.4.7)
+ '@storybook/addon-onboarding':
+ specifier: ^8.4.7
+ version: 8.4.7(react@18.3.1)(storybook@8.4.7)
+ '@storybook/blocks':
+ specifier: ^8.4.7
+ version: 8.4.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7)
+ '@storybook/react':
+ specifier: ^8.4.7
+ version: 8.4.7(@storybook/test@8.4.7(storybook@8.4.7))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7)(typescript@5.6.3)
+ '@storybook/react-vite':
+ specifier: ^8.4.7
+ version: 8.4.7(@storybook/test@8.4.7(storybook@8.4.7))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.28.0)(storybook@8.4.7)(typescript@5.6.3)(vite@6.0.3(@types/node@22.10.2))
+ '@storybook/test':
+ specifier: ^8.4.7
+ version: 8.4.7(storybook@8.4.7)
+ '@types/jwt-decode':
+ specifier: ^3.1.0
+ version: 3.1.0
'@types/react':
- specifier: ^18.3.12
+ specifier: ^18.3.14
version: 18.3.14
'@types/react-dom':
- specifier: ^18.3.1
+ specifier: ^18.3.2
version: 18.3.2
+ '@types/redux-persist':
+ specifier: ^4.3.1
+ version: 4.3.1(react@18.3.1)(redux@5.0.1)
'@vitejs/plugin-react':
specifier: ^4.3.4
- version: 4.3.4(vite@6.0.3)
+ version: 4.3.4(vite@6.0.3(@types/node@22.10.2))
eslint:
specifier: ^9.15.0
version: 9.16.0
@@ -51,9 +111,21 @@ importers:
eslint-plugin-react-refresh:
specifier: ^0.4.14
version: 0.4.16(eslint@9.16.0)
+ eslint-plugin-storybook:
+ specifier: ^0.11.1
+ version: 0.11.1(eslint@9.16.0)(typescript@5.6.3)
globals:
specifier: ^15.12.0
version: 15.13.0
+ husky:
+ specifier: ^9.1.7
+ version: 9.1.7
+ msw:
+ specifier: ^2.6.8
+ version: 2.6.8(@types/node@22.10.2)(typescript@5.6.3)
+ storybook:
+ specifier: ^8.4.7
+ version: 8.4.7
typescript:
specifier: ~5.6.2
version: 5.6.3
@@ -61,11 +133,20 @@ importers:
specifier: ^8.15.0
version: 8.17.0(eslint@9.16.0)(typescript@5.6.3)
vite:
- specifier: ^6.0.1
- version: 6.0.3
+ specifier: ^6.0.3
+ version: 6.0.3(@types/node@22.10.2)
+ vite-plugin-svgr:
+ specifier: ^4.3.0
+ version: 4.3.0(rollup@4.28.0)(typescript@5.6.3)(vite@6.0.3(@types/node@22.10.2))
+ vitest:
+ specifier: ^2.1.8
+ version: 2.1.8(@types/node@22.10.2)(msw@2.6.8(@types/node@22.10.2)(typescript@5.6.3))
packages:
+ '@adobe/css-tools@4.4.1':
+ resolution: {integrity: sha512-12WGKBQzjUAI4ayyF4IAtfw2QR/IDoqk6jTddXDhtYTJF9ASmoE1zst7cVtP0aL/F1jUJL5r+JxKXKEgHNbEUQ==}
+
'@ampproject/remapping@2.3.0':
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
engines: {node: '>=6.0.0'}
@@ -137,6 +218,10 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0-0
+ '@babel/runtime@7.26.0':
+ resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==}
+ engines: {node: '>=6.9.0'}
+
'@babel/template@7.25.9':
resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==}
engines: {node: '>=6.9.0'}
@@ -149,6 +234,21 @@ packages:
resolution: {integrity: sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==}
engines: {node: '>=6.9.0'}
+ '@bundled-es-modules/cookie@2.0.1':
+ resolution: {integrity: sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==}
+
+ '@bundled-es-modules/statuses@1.0.1':
+ resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==}
+
+ '@bundled-es-modules/tough-cookie@0.1.6':
+ resolution: {integrity: sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==}
+
+ '@chromatic-com/storybook@3.2.2':
+ resolution: {integrity: sha512-xmXt/GW0hAPbzNTrxYuVo43Adrtjue4DeVrsoIIEeJdGaPNNeNf+DHMlJKOBdlHmCnFUoe9R/0mLM9zUp5bKWw==}
+ engines: {node: '>=16.0.0', yarn: '>=1.22.18'}
+ peerDependencies:
+ storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0
+
'@emotion/is-prop-valid@1.2.2':
resolution: {integrity: sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==}
@@ -158,108 +258,216 @@ packages:
'@emotion/unitless@0.8.1':
resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==}
+ '@esbuild/aix-ppc64@0.21.5':
+ resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [aix]
+
'@esbuild/aix-ppc64@0.24.0':
resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [aix]
+ '@esbuild/android-arm64@0.21.5':
+ resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [android]
+
'@esbuild/android-arm64@0.24.0':
resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==}
engines: {node: '>=18'}
cpu: [arm64]
os: [android]
+ '@esbuild/android-arm@0.21.5':
+ resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [android]
+
'@esbuild/android-arm@0.24.0':
resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==}
engines: {node: '>=18'}
cpu: [arm]
os: [android]
+ '@esbuild/android-x64@0.21.5':
+ resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [android]
+
'@esbuild/android-x64@0.24.0':
resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [android]
+ '@esbuild/darwin-arm64@0.21.5':
+ resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [darwin]
+
'@esbuild/darwin-arm64@0.24.0':
resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==}
engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
+ '@esbuild/darwin-x64@0.21.5':
+ resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [darwin]
+
'@esbuild/darwin-x64@0.24.0':
resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==}
engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
+ '@esbuild/freebsd-arm64@0.21.5':
+ resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [freebsd]
+
'@esbuild/freebsd-arm64@0.24.0':
resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==}
engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
+ '@esbuild/freebsd-x64@0.21.5':
+ resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [freebsd]
+
'@esbuild/freebsd-x64@0.24.0':
resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
+ '@esbuild/linux-arm64@0.21.5':
+ resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [linux]
+
'@esbuild/linux-arm64@0.24.0':
resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==}
engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
+ '@esbuild/linux-arm@0.21.5':
+ resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [linux]
+
'@esbuild/linux-arm@0.24.0':
resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==}
engines: {node: '>=18'}
cpu: [arm]
os: [linux]
+ '@esbuild/linux-ia32@0.21.5':
+ resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [linux]
+
'@esbuild/linux-ia32@0.24.0':
resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==}
engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
+ '@esbuild/linux-loong64@0.21.5':
+ resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
+ engines: {node: '>=12'}
+ cpu: [loong64]
+ os: [linux]
+
'@esbuild/linux-loong64@0.24.0':
resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==}
engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
+ '@esbuild/linux-mips64el@0.21.5':
+ resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
+ engines: {node: '>=12'}
+ cpu: [mips64el]
+ os: [linux]
+
'@esbuild/linux-mips64el@0.24.0':
resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==}
engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
+ '@esbuild/linux-ppc64@0.21.5':
+ resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [linux]
+
'@esbuild/linux-ppc64@0.24.0':
resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
+ '@esbuild/linux-riscv64@0.21.5':
+ resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
+ engines: {node: '>=12'}
+ cpu: [riscv64]
+ os: [linux]
+
'@esbuild/linux-riscv64@0.24.0':
resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==}
engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
+ '@esbuild/linux-s390x@0.21.5':
+ resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
+ engines: {node: '>=12'}
+ cpu: [s390x]
+ os: [linux]
+
'@esbuild/linux-s390x@0.24.0':
resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==}
engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
+ '@esbuild/linux-x64@0.21.5':
+ resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [linux]
+
'@esbuild/linux-x64@0.24.0':
resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==}
engines: {node: '>=18'}
cpu: [x64]
os: [linux]
+ '@esbuild/netbsd-x64@0.21.5':
+ resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [netbsd]
+
'@esbuild/netbsd-x64@0.24.0':
resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==}
engines: {node: '>=18'}
@@ -272,30 +480,60 @@ packages:
cpu: [arm64]
os: [openbsd]
+ '@esbuild/openbsd-x64@0.21.5':
+ resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [openbsd]
+
'@esbuild/openbsd-x64@0.24.0':
resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==}
engines: {node: '>=18'}
cpu: [x64]
os: [openbsd]
+ '@esbuild/sunos-x64@0.21.5':
+ resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [sunos]
+
'@esbuild/sunos-x64@0.24.0':
resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==}
engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
+ '@esbuild/win32-arm64@0.21.5':
+ resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [win32]
+
'@esbuild/win32-arm64@0.24.0':
resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==}
engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
+ '@esbuild/win32-ia32@0.21.5':
+ resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [win32]
+
'@esbuild/win32-ia32@0.24.0':
resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==}
engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
+ '@esbuild/win32-x64@0.21.5':
+ resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [win32]
+
'@esbuild/win32-x64@0.24.0':
resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==}
engines: {node: '>=18'}
@@ -336,6 +574,11 @@ packages:
resolution: {integrity: sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ '@heroicons/react@2.2.0':
+ resolution: {integrity: sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==}
+ peerDependencies:
+ react: '>= 16 || ^19.0.0-rc'
+
'@humanfs/core@0.19.1':
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
engines: {node: '>=18.18.0'}
@@ -356,6 +599,35 @@ packages:
resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==}
engines: {node: '>=18.18'}
+ '@inquirer/confirm@5.1.0':
+ resolution: {integrity: sha512-osaBbIMEqVFjTX5exoqPXs6PilWQdjaLhGtMDXMXg/yxkHXNq43GlxGyTA35lK2HpzUgDN+Cjh/2AmqCN0QJpw==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@types/node': '>=18'
+
+ '@inquirer/core@10.1.1':
+ resolution: {integrity: sha512-rmZVXy9iZvO3ZStEe/ayuuwIJ23LSF13aPMlLMTQARX6lGUBDHGV8UB5i9MRrfy0+mZwt5/9bdy8llszSD3NQA==}
+ engines: {node: '>=18'}
+
+ '@inquirer/figures@1.0.8':
+ resolution: {integrity: sha512-tKd+jsmhq21AP1LhexC0pPwsCxEhGgAkg28byjJAd+xhmIs8LUX8JbUc3vBf3PhLxWiB5EvyBE5X7JSPAqMAqg==}
+ engines: {node: '>=18'}
+
+ '@inquirer/type@3.0.1':
+ resolution: {integrity: sha512-+ksJMIy92sOAiAccGpcKZUc3bYO07cADnscIxHBknEm3uNts3movSmBofc1908BNy5edKscxYeAdaX1NXkHS6A==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@types/node': '>=18'
+
+ '@joshwooding/vite-plugin-react-docgen-typescript@0.4.2':
+ resolution: {integrity: sha512-feQ+ntr+8hbVudnsTUapiMN9q8T90XA1d5jn9QzY09sNoj4iD9wi0PY1vsBFTda4ZjEaxRK9S81oarR2nj7TFQ==}
+ peerDependencies:
+ typescript: '>= 4.3.x'
+ vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
'@jridgewell/gen-mapping@0.3.5':
resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
engines: {node: '>=6.0.0'}
@@ -374,6 +646,16 @@ packages:
'@jridgewell/trace-mapping@0.3.25':
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
+ '@mdx-js/react@3.1.0':
+ resolution: {integrity: sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==}
+ peerDependencies:
+ '@types/react': '>=16'
+ react: '>=16'
+
+ '@mswjs/interceptors@0.37.3':
+ resolution: {integrity: sha512-USvgCL/uOGFtVa6SVyRrC8kIAedzRohxIXN5LISlg5C5vLZCn7dgMFVSNhSF9cuBEFrm/O2spDWEZeMnw4ZXYg==}
+ engines: {node: '>=18'}
+
'@nodelib/fs.scandir@2.1.5':
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'}
@@ -386,6 +668,15 @@ packages:
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'}
+ '@open-draft/deferred-promise@2.2.0':
+ resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==}
+
+ '@open-draft/logger@0.3.0':
+ resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==}
+
+ '@open-draft/until@2.1.0':
+ resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==}
+
'@reduxjs/toolkit@2.4.0':
resolution: {integrity: sha512-wJZEuSKj14tvNfxiIiJws0tQN77/rDqucBq528ApebMIRHyWpCanJVQRxQ8WWZC19iCDKxDsGlbAir3F1layxA==}
peerDependencies:
@@ -397,6 +688,15 @@ packages:
react-redux:
optional: true
+ '@rollup/pluginutils@5.1.3':
+ resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
+ peerDependenciesMeta:
+ rollup:
+ optional: true
+
'@rollup/rollup-android-arm-eabi@4.28.0':
resolution: {integrity: sha512-wLJuPLT6grGZsy34g4N1yRfYeouklTgPhH1gWXCYspenKYD0s3cR99ZevOGw5BexMNywkbV3UkjADisozBmpPQ==}
cpu: [arm]
@@ -487,6 +787,239 @@ packages:
cpu: [x64]
os: [win32]
+ '@storybook/addon-actions@8.4.7':
+ resolution: {integrity: sha512-mjtD5JxcPuW74T6h7nqMxWTvDneFtokg88p6kQ5OnC1M259iAXb//yiSZgu/quunMHPCXSiqn4FNOSgASTSbsA==}
+ peerDependencies:
+ storybook: ^8.4.7
+
+ '@storybook/addon-backgrounds@8.4.7':
+ resolution: {integrity: sha512-I4/aErqtFiazcoWyKafOAm3bLpxTj6eQuH/woSbk1Yx+EzN+Dbrgx1Updy8//bsNtKkcrXETITreqHC+a57DHQ==}
+ peerDependencies:
+ storybook: ^8.4.7
+
+ '@storybook/addon-controls@8.4.7':
+ resolution: {integrity: sha512-377uo5IsJgXLnQLJixa47+11V+7Wn9KcDEw+96aGCBCfLbWNH8S08tJHHnSu+jXg9zoqCAC23MetntVp6LetHA==}
+ peerDependencies:
+ storybook: ^8.4.7
+
+ '@storybook/addon-docs@8.4.7':
+ resolution: {integrity: sha512-NwWaiTDT5puCBSUOVuf6ME7Zsbwz7Y79WF5tMZBx/sLQ60vpmJVQsap6NSjvK1Ravhc21EsIXqemAcBjAWu80w==}
+ peerDependencies:
+ storybook: ^8.4.7
+
+ '@storybook/addon-essentials@8.4.7':
+ resolution: {integrity: sha512-+BtZHCBrYtQKILtejKxh0CDRGIgTl9PumfBOKRaihYb4FX1IjSAxoV/oo/IfEjlkF5f87vouShWsRa8EUauFDw==}
+ peerDependencies:
+ storybook: ^8.4.7
+
+ '@storybook/addon-highlight@8.4.7':
+ resolution: {integrity: sha512-whQIDBd3PfVwcUCrRXvCUHWClXe9mQ7XkTPCdPo4B/tZ6Z9c6zD8JUHT76ddyHivixFLowMnA8PxMU6kCMAiNw==}
+ peerDependencies:
+ storybook: ^8.4.7
+
+ '@storybook/addon-interactions@8.4.7':
+ resolution: {integrity: sha512-fnufT3ym8ht3HHUIRVXAH47iOJW/QOb0VSM+j269gDuvyDcY03D1civCu1v+eZLGaXPKJ8vtjr0L8zKQ/4P0JQ==}
+ peerDependencies:
+ storybook: ^8.4.7
+
+ '@storybook/addon-measure@8.4.7':
+ resolution: {integrity: sha512-QfvqYWDSI5F68mKvafEmZic3SMiK7zZM8VA0kTXx55hF/+vx61Mm0HccApUT96xCXIgmwQwDvn9gS4TkX81Dmw==}
+ peerDependencies:
+ storybook: ^8.4.7
+
+ '@storybook/addon-onboarding@8.4.7':
+ resolution: {integrity: sha512-FdC2NV60VNYeMxf6DVe0qV9ucSBAzMh1//C0Qqwq8CcjthMbmKlVZ7DqbVsbIHKnFaSCaUC88eR5olAfMaauCQ==}
+ peerDependencies:
+ storybook: ^8.4.7
+
+ '@storybook/addon-outline@8.4.7':
+ resolution: {integrity: sha512-6LYRqUZxSodmAIl8icr585Oi8pmzbZ90aloZJIpve+dBAzo7ydYrSQxxoQEVltXbKf3VeVcrs64ouAYqjisMYA==}
+ peerDependencies:
+ storybook: ^8.4.7
+
+ '@storybook/addon-toolbars@8.4.7':
+ resolution: {integrity: sha512-OSfdv5UZs+NdGB+nZmbafGUWimiweJ/56gShlw8Neo/4jOJl1R3rnRqqY7MYx8E4GwoX+i3GF5C3iWFNQqlDcw==}
+ peerDependencies:
+ storybook: ^8.4.7
+
+ '@storybook/addon-viewport@8.4.7':
+ resolution: {integrity: sha512-hvczh/jjuXXcOogih09a663sRDDSATXwbE866al1DXgbDFraYD/LxX/QDb38W9hdjU9+Qhx8VFIcNWoMQns5HQ==}
+ peerDependencies:
+ storybook: ^8.4.7
+
+ '@storybook/blocks@8.4.7':
+ resolution: {integrity: sha512-+QH7+JwXXXIyP3fRCxz/7E2VZepAanXJM7G8nbR3wWsqWgrRp4Wra6MvybxAYCxU7aNfJX5c+RW84SNikFpcIA==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
+ react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
+ storybook: ^8.4.7
+ peerDependenciesMeta:
+ react:
+ optional: true
+ react-dom:
+ optional: true
+
+ '@storybook/builder-vite@8.4.7':
+ resolution: {integrity: sha512-LovyXG5VM0w7CovI/k56ZZyWCveQFVDl0m7WwetpmMh2mmFJ+uPQ35BBsgTvTfc8RHi+9Q3F58qP1MQSByXi9g==}
+ peerDependencies:
+ storybook: ^8.4.7
+ vite: ^4.0.0 || ^5.0.0 || ^6.0.0
+
+ '@storybook/components@8.4.7':
+ resolution: {integrity: sha512-uyJIcoyeMWKAvjrG9tJBUCKxr2WZk+PomgrgrUwejkIfXMO76i6jw9BwLa0NZjYdlthDv30r9FfbYZyeNPmF0g==}
+ peerDependencies:
+ storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0
+
+ '@storybook/core@8.4.7':
+ resolution: {integrity: sha512-7Z8Z0A+1YnhrrSXoKKwFFI4gnsLbWzr8fnDCU6+6HlDukFYh8GHRcZ9zKfqmy6U3hw2h8H5DrHsxWfyaYUUOoA==}
+ peerDependencies:
+ prettier: ^2 || ^3
+ peerDependenciesMeta:
+ prettier:
+ optional: true
+
+ '@storybook/csf-plugin@8.4.7':
+ resolution: {integrity: sha512-Fgogplu4HImgC+AYDcdGm1rmL6OR1rVdNX1Be9C/NEXwOCpbbBwi0BxTf/2ZxHRk9fCeaPEcOdP5S8QHfltc1g==}
+ peerDependencies:
+ storybook: ^8.4.7
+
+ '@storybook/csf@0.1.12':
+ resolution: {integrity: sha512-9/exVhabisyIVL0VxTCxo01Tdm8wefIXKXfltAPTSr8cbLn5JAxGQ6QV3mjdecLGEOucfoVhAKtJfVHxEK1iqw==}
+
+ '@storybook/global@5.0.0':
+ resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==}
+
+ '@storybook/icons@1.3.0':
+ resolution: {integrity: sha512-Nz/UzeYQdUZUhacrPyfkiiysSjydyjgg/p0P9HxB4p/WaJUUjMAcaoaLgy3EXx61zZJ3iD36WPuDkZs5QYrA0A==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
+ react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
+
+ '@storybook/instrumenter@8.4.7':
+ resolution: {integrity: sha512-k6NSD3jaRCCHAFtqXZ7tw8jAzD/yTEWXGya+REgZqq5RCkmJ+9S4Ytp/6OhQMPtPFX23gAuJJzTQVLcCr+gjRg==}
+ peerDependencies:
+ storybook: ^8.4.7
+
+ '@storybook/manager-api@8.4.7':
+ resolution: {integrity: sha512-ELqemTviCxAsZ5tqUz39sDmQkvhVAvAgiplYy9Uf15kO0SP2+HKsCMzlrm2ue2FfkUNyqbDayCPPCB0Cdn/mpQ==}
+ peerDependencies:
+ storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0
+
+ '@storybook/preview-api@8.4.7':
+ resolution: {integrity: sha512-0QVQwHw+OyZGHAJEXo6Knx+6/4er7n2rTDE5RYJ9F2E2Lg42E19pfdLlq2Jhoods2Xrclo3wj6GWR//Ahi39Eg==}
+ peerDependencies:
+ storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0
+
+ '@storybook/react-dom-shim@8.4.7':
+ resolution: {integrity: sha512-6bkG2jvKTmWrmVzCgwpTxwIugd7Lu+2btsLAqhQSzDyIj2/uhMNp8xIMr/NBDtLgq3nomt9gefNa9xxLwk/OMg==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
+ react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
+ storybook: ^8.4.7
+
+ '@storybook/react-vite@8.4.7':
+ resolution: {integrity: sha512-iiY9iLdMXhDnilCEVxU6vQsN72pW3miaf0WSenOZRyZv3HdbpgOxI0qapOS0KCyRUnX9vTlmrSPTMchY4cAeOg==}
+ engines: {node: '>=18.0.0'}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
+ react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
+ storybook: ^8.4.7
+ vite: ^4.0.0 || ^5.0.0 || ^6.0.0
+
+ '@storybook/react@8.4.7':
+ resolution: {integrity: sha512-nQ0/7i2DkaCb7dy0NaT95llRVNYWQiPIVuhNfjr1mVhEP7XD090p0g7eqUmsx8vfdHh2BzWEo6CoBFRd3+EXxw==}
+ engines: {node: '>=18.0.0'}
+ peerDependencies:
+ '@storybook/test': 8.4.7
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
+ react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
+ storybook: ^8.4.7
+ typescript: '>= 4.2.x'
+ peerDependenciesMeta:
+ '@storybook/test':
+ optional: true
+ typescript:
+ optional: true
+
+ '@storybook/test@8.4.7':
+ resolution: {integrity: sha512-AhvJsu5zl3uG40itSQVuSy5WByp3UVhS6xAnme4FWRwgSxhvZjATJ3AZkkHWOYjnnk+P2/sbz/XuPli1FVCWoQ==}
+ peerDependencies:
+ storybook: ^8.4.7
+
+ '@storybook/theming@8.4.7':
+ resolution: {integrity: sha512-99rgLEjf7iwfSEmdqlHkSG3AyLcK0sfExcr0jnc6rLiAkBhzuIsvcHjjUwkR210SOCgXqBPW0ZA6uhnuyppHLw==}
+ peerDependencies:
+ storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0
+
+ '@svgr/babel-plugin-add-jsx-attribute@8.0.0':
+ resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-remove-jsx-attribute@8.0.0':
+ resolution: {integrity: sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0':
+ resolution: {integrity: sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0':
+ resolution: {integrity: sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-svg-dynamic-title@8.0.0':
+ resolution: {integrity: sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-svg-em-dimensions@8.0.0':
+ resolution: {integrity: sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-transform-react-native-svg@8.1.0':
+ resolution: {integrity: sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-transform-svg-component@8.0.0':
+ resolution: {integrity: sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==}
+ engines: {node: '>=12'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-preset@8.1.0':
+ resolution: {integrity: sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/core@8.1.0':
+ resolution: {integrity: sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==}
+ engines: {node: '>=14'}
+
+ '@svgr/hast-util-to-babel-ast@8.0.0':
+ resolution: {integrity: sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==}
+ engines: {node: '>=14'}
+
+ '@svgr/plugin-jsx@8.1.0':
+ resolution: {integrity: sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@svgr/core': '*'
+
'@tanstack/query-core@5.62.2':
resolution: {integrity: sha512-LcwVcC5qpsDpHcqlXUUL5o9SaOBwhNkGeV+B06s0GBoyBr8FqXPuXT29XzYXR36lchhnerp6XO+CWc84/vh7Zg==}
@@ -495,6 +1028,23 @@ packages:
peerDependencies:
react: ^18 || ^19
+ '@testing-library/dom@10.4.0':
+ resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==}
+ engines: {node: '>=18'}
+
+ '@testing-library/jest-dom@6.5.0':
+ resolution: {integrity: sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==}
+ engines: {node: '>=14', npm: '>=6', yarn: '>=1'}
+
+ '@testing-library/user-event@14.5.2':
+ resolution: {integrity: sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==}
+ engines: {node: '>=12', npm: '>=6'}
+ peerDependencies:
+ '@testing-library/dom': '>=7.21.4'
+
+ '@types/aria-query@5.0.4':
+ resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==}
+
'@types/babel__core@7.20.5':
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
@@ -510,27 +1060,71 @@ packages:
'@types/cookie@0.6.0':
resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
+ '@types/doctrine@0.0.9':
+ resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==}
+
'@types/estree@1.0.6':
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
+ '@types/hoist-non-react-statics@3.3.6':
+ resolution: {integrity: sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==}
+
'@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
+ '@types/jwt-decode@3.1.0':
+ resolution: {integrity: sha512-tthwik7TKkou3mVnBnvVuHnHElbjtdbM63pdBCbZTirCt3WAdM73Y79mOri7+ljsS99ZVwUFZHLMxJuJnv/z1w==}
+ deprecated: This is a stub types definition. jwt-decode provides its own type definitions, so you do not need this installed.
+
+ '@types/mdx@2.0.13':
+ resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==}
+
+ '@types/node@22.10.2':
+ resolution: {integrity: sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==}
+
'@types/prop-types@15.7.14':
resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==}
+ '@types/quill@1.3.10':
+ resolution: {integrity: sha512-IhW3fPW+bkt9MLNlycw8u8fWb7oO7W5URC9MfZYHBlA24rex9rs23D5DETChu1zvgVdc5ka64ICjJOgQMr6Shw==}
+
+ '@types/quill@2.0.14':
+ resolution: {integrity: sha512-zvoXCRnc2Dl8g+7/9VSAmRWPN6oH+MVhTPizmCR+GJCITplZ5VRVzMs4+a/nOE3yzNwEZqylJJrMB07bwbM1/g==}
+
'@types/react-dom@18.3.2':
resolution: {integrity: sha512-Fqp+rcvem9wEnGr3RY8dYNvSQ8PoLqjZ9HLgaPUOjJJD120uDyOxOjc/39M4Kddp9JQCxpGQbnhVQF0C0ncYVg==}
+ '@types/react-redux@7.1.34':
+ resolution: {integrity: sha512-GdFaVjEbYv4Fthm2ZLvj1VSCedV7TqE5y1kNwnjSdBOTXuRSgowux6J8TAct15T3CKBr63UMk+2CO7ilRhyrAQ==}
+
'@types/react@18.3.14':
resolution: {integrity: sha512-NzahNKvjNhVjuPBQ+2G7WlxstQ+47kXZNHlUvFakDViuIEfGY926GqhMueQFZ7woG+sPiQKlF36XfrIUVSUfFg==}
+ '@types/redux-persist@4.3.1':
+ resolution: {integrity: sha512-YkMnMUk+4//wPtiSTMfsxST/F9Gh9sPWX0LVxHuOidGjojHtMdpep2cYvQgfiDMnj34orXyZI+QJCQMZDlafKA==}
+ deprecated: This is a stub types definition for redux-persist (https://github.com/rt2zz/redux-persist). redux-persist provides its own type definitions, so you don't need @types/redux-persist installed!
+
+ '@types/resolve@1.20.6':
+ resolution: {integrity: sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==}
+
+ '@types/statuses@2.0.5':
+ resolution: {integrity: sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==}
+
'@types/stylis@4.2.5':
resolution: {integrity: sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==}
+ '@types/tough-cookie@4.0.5':
+ resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==}
+
+ '@types/trusted-types@2.0.7':
+ resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
+
'@types/use-sync-external-store@0.0.3':
resolution: {integrity: sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==}
+ '@types/uuid@9.0.8':
+ resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==}
+
'@typescript-eslint/eslint-plugin@8.17.0':
resolution: {integrity: sha512-HU1KAdW3Tt8zQkdvNoIijfWDMvdSweFYm4hWh+KwhPstv+sCmWb89hCIP8msFm9N1R/ooh9honpSuvqKWlYy3w==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -599,6 +1193,47 @@ packages:
peerDependencies:
vite: ^4.2.0 || ^5.0.0 || ^6.0.0
+ '@vitest/expect@2.0.5':
+ resolution: {integrity: sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==}
+
+ '@vitest/expect@2.1.8':
+ resolution: {integrity: sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw==}
+
+ '@vitest/mocker@2.1.8':
+ resolution: {integrity: sha512-7guJ/47I6uqfttp33mgo6ga5Gr1VnL58rcqYKyShoRK9ebu8T5Rs6HN3s1NABiBeVTdWNrwUMcHH54uXZBN4zA==}
+ peerDependencies:
+ msw: ^2.4.9
+ vite: ^5.0.0
+ peerDependenciesMeta:
+ msw:
+ optional: true
+ vite:
+ optional: true
+
+ '@vitest/pretty-format@2.0.5':
+ resolution: {integrity: sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==}
+
+ '@vitest/pretty-format@2.1.8':
+ resolution: {integrity: sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==}
+
+ '@vitest/runner@2.1.8':
+ resolution: {integrity: sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg==}
+
+ '@vitest/snapshot@2.1.8':
+ resolution: {integrity: sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg==}
+
+ '@vitest/spy@2.0.5':
+ resolution: {integrity: sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==}
+
+ '@vitest/spy@2.1.8':
+ resolution: {integrity: sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg==}
+
+ '@vitest/utils@2.0.5':
+ resolution: {integrity: sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==}
+
+ '@vitest/utils@2.1.8':
+ resolution: {integrity: sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==}
+
acorn-jsx@5.3.2:
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
peerDependencies:
@@ -612,16 +1247,61 @@ packages:
ajv@6.12.6:
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
+ ansi-escapes@4.3.2:
+ resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==}
+ engines: {node: '>=8'}
+
+ ansi-regex@5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
+
+ ansi-regex@6.1.0:
+ resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==}
+ engines: {node: '>=12'}
+
ansi-styles@4.3.0:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
+ ansi-styles@5.2.0:
+ resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
+ engines: {node: '>=10'}
+
argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+ aria-query@5.3.0:
+ resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==}
+
+ aria-query@5.3.2:
+ resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
+ engines: {node: '>= 0.4'}
+
+ assertion-error@2.0.1:
+ resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
+ engines: {node: '>=12'}
+
+ ast-types@0.16.1:
+ resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==}
+ engines: {node: '>=4'}
+
+ asynckit@0.4.0:
+ resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
+
+ available-typed-arrays@1.0.7:
+ resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
+ engines: {node: '>= 0.4'}
+
+ axios@1.7.9:
+ resolution: {integrity: sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==}
+
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+ better-opn@3.0.2:
+ resolution: {integrity: sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==}
+ engines: {node: '>=12.0.0'}
+
brace-expansion@1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
@@ -632,25 +1312,88 @@ packages:
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
engines: {node: '>=8'}
+ browser-assert@1.2.1:
+ resolution: {integrity: sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==}
+
browserslist@4.24.2:
resolution: {integrity: sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
- callsites@3.1.0:
- resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
+ cac@6.7.14:
+ resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
+ engines: {node: '>=8'}
+
+ call-bind-apply-helpers@1.0.0:
+ resolution: {integrity: sha512-CCKAP2tkPau7D3GE8+V8R6sQubA9R5foIzGp+85EXCVSCivuxBNAWqcpn72PKYiIcqoViv/kcUDpaEIMBVi1lQ==}
+ engines: {node: '>= 0.4'}
+
+ call-bind-apply-helpers@1.0.1:
+ resolution: {integrity: sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==}
+ engines: {node: '>= 0.4'}
+
+ call-bind@1.0.8:
+ resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==}
+ engines: {node: '>= 0.4'}
+
+ call-bound@1.0.3:
+ resolution: {integrity: sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==}
+ engines: {node: '>= 0.4'}
+
+ callsites@3.1.0:
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'}
+ camelcase@6.3.0:
+ resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
+ engines: {node: '>=10'}
+
camelize@1.0.1:
resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==}
caniuse-lite@1.0.30001686:
resolution: {integrity: sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA==}
+ chai@5.1.2:
+ resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==}
+ engines: {node: '>=12'}
+
+ chalk@3.0.0:
+ resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==}
+ engines: {node: '>=8'}
+
chalk@4.1.2:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
engines: {node: '>=10'}
+ check-error@2.1.1:
+ resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==}
+ engines: {node: '>= 16'}
+
+ chromatic@11.20.0:
+ resolution: {integrity: sha512-Btdli1qoAI01UKmk3Iqe6vKhAhePRXqNI/2uKKy2R16q7SN/5kLTqhd1JI20LFOZSnH3xSJaUXeJ2xZOJB//3A==}
+ hasBin: true
+ peerDependencies:
+ '@chromatic-com/cypress': ^0.*.* || ^1.0.0
+ '@chromatic-com/playwright': ^0.*.* || ^1.0.0
+ peerDependenciesMeta:
+ '@chromatic-com/cypress':
+ optional: true
+ '@chromatic-com/playwright':
+ optional: true
+
+ cli-width@4.1.0:
+ resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==}
+ engines: {node: '>= 12'}
+
+ cliui@8.0.1:
+ resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
+ engines: {node: '>=12'}
+
+ clone@2.1.2:
+ resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==}
+ engines: {node: '>=0.8'}
+
color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
@@ -658,16 +1401,33 @@ packages:
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+ combined-stream@1.0.8:
+ resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
+ engines: {node: '>= 0.8'}
+
concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
+ cookie@0.7.2:
+ resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
+ engines: {node: '>= 0.6'}
+
cookie@1.0.2:
resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==}
engines: {node: '>=18'}
+ cosmiconfig@8.3.6:
+ resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ typescript: '>=4.9.5'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
cross-spawn@7.0.6:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
@@ -679,6 +1439,9 @@ packages:
css-to-react-native@3.2.0:
resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==}
+ css.escape@1.5.1:
+ resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==}
+
csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
@@ -691,12 +1454,95 @@ packages:
supports-color:
optional: true
+ deep-eql@5.0.2:
+ resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==}
+ engines: {node: '>=6'}
+
+ deep-equal@1.1.2:
+ resolution: {integrity: sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==}
+ engines: {node: '>= 0.4'}
+
deep-is@0.1.4:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
+ define-data-property@1.1.4:
+ resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
+ engines: {node: '>= 0.4'}
+
+ define-lazy-prop@2.0.0:
+ resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==}
+ engines: {node: '>=8'}
+
+ define-properties@1.2.1:
+ resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
+ engines: {node: '>= 0.4'}
+
+ delayed-stream@1.0.0:
+ resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
+ engines: {node: '>=0.4.0'}
+
+ dequal@2.0.3:
+ resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
+ engines: {node: '>=6'}
+
+ doctrine@3.0.0:
+ resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
+ engines: {node: '>=6.0.0'}
+
+ dom-accessibility-api@0.5.16:
+ resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==}
+
+ dom-accessibility-api@0.6.3:
+ resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==}
+
+ dompurify@3.2.3:
+ resolution: {integrity: sha512-U1U5Hzc2MO0oW3DF+G9qYN0aT7atAou4AgI0XjWz061nyBPbdxkfdhfy5uMgGn6+oLFCfn44ZGbdDqCzVmlOWA==}
+
+ dot-case@3.0.4:
+ resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
+
+ dunder-proto@1.0.0:
+ resolution: {integrity: sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==}
+ engines: {node: '>= 0.4'}
+
electron-to-chromium@1.5.71:
resolution: {integrity: sha512-dB68l59BI75W1BUGVTAEJy45CEVuEGy9qPVVQ8pnHyHMn36PLPPoE1mjLH+lo9rKulO3HC2OhbACI/8tCqJBcA==}
+ emoji-regex@8.0.0:
+ resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+
+ entities@4.5.0:
+ resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+ engines: {node: '>=0.12'}
+
+ error-ex@1.3.2:
+ resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
+
+ es-define-property@1.0.1:
+ resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
+ engines: {node: '>= 0.4'}
+
+ es-errors@1.3.0:
+ resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
+ engines: {node: '>= 0.4'}
+
+ es-module-lexer@1.5.4:
+ resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==}
+
+ es-object-atoms@1.0.0:
+ resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==}
+ engines: {node: '>= 0.4'}
+
+ esbuild-register@3.6.0:
+ resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==}
+ peerDependencies:
+ esbuild: '>=0.12 <1'
+
+ esbuild@0.21.5:
+ resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==}
+ engines: {node: '>=12'}
+ hasBin: true
+
esbuild@0.24.0:
resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==}
engines: {node: '>=18'}
@@ -721,6 +1567,12 @@ packages:
peerDependencies:
eslint: '>=8.40'
+ eslint-plugin-storybook@0.11.1:
+ resolution: {integrity: sha512-yGKpAYkBm/Q2hZg476vRUAvd9lAccjjSvzU5nYy3BSQbKTPy7uopx7JEpwk2vSuw4weTMZzWF64z9/gp/K5RCg==}
+ engines: {node: '>= 18'}
+ peerDependencies:
+ eslint: '>=6'
+
eslint-scope@8.2.0:
resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -747,6 +1599,11 @@ packages:
resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ esprima@4.0.1:
+ resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
+ engines: {node: '>=4'}
+ hasBin: true
+
esquery@1.6.0:
resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==}
engines: {node: '>=0.10'}
@@ -759,13 +1616,38 @@ packages:
resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
engines: {node: '>=4.0'}
+ estree-walker@2.0.2:
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
+ estree-walker@3.0.3:
+ resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+
esutils@2.0.3:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'}
+ eventemitter3@2.0.3:
+ resolution: {integrity: sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==}
+
+ eventemitter3@5.0.1:
+ resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
+
+ expect-type@1.1.0:
+ resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==}
+ engines: {node: '>=12.0.0'}
+
+ extend@3.0.2:
+ resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
+
fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+ fast-diff@1.1.2:
+ resolution: {integrity: sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==}
+
+ fast-diff@1.3.0:
+ resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
+
fast-glob@3.3.2:
resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
engines: {node: '>=8.6.0'}
@@ -783,6 +1665,10 @@ packages:
resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
engines: {node: '>=16.0.0'}
+ filesize@10.1.6:
+ resolution: {integrity: sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w==}
+ engines: {node: '>= 10.4.0'}
+
fill-range@7.1.1:
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
engines: {node: '>=8'}
@@ -798,15 +1684,49 @@ packages:
flatted@3.3.2:
resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==}
+ follow-redirects@1.15.9:
+ resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
+ engines: {node: '>=4.0'}
+ peerDependencies:
+ debug: '*'
+ peerDependenciesMeta:
+ debug:
+ optional: true
+
+ for-each@0.3.3:
+ resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
+
+ form-data@4.0.1:
+ resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==}
+ engines: {node: '>= 6'}
+
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
+ function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+
+ functions-have-names@1.2.3:
+ resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
+
gensync@1.0.0-beta.2:
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
engines: {node: '>=6.9.0'}
+ get-caller-file@2.0.5:
+ resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
+ engines: {node: 6.* || 8.* || >= 10.*}
+
+ get-intrinsic@1.2.5:
+ resolution: {integrity: sha512-Y4+pKa7XeRUPWFNvOOYHkRYrfzW07oraURSvjDmRVOJ748OrVmeXtpE4+GCEHncjCjkTxPNRt8kEbxDhsn6VTg==}
+ engines: {node: '>= 0.4'}
+
+ get-intrinsic@1.2.6:
+ resolution: {integrity: sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==}
+ engines: {node: '>= 0.4'}
+
glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
@@ -827,13 +1747,50 @@ packages:
resolution: {integrity: sha512-49TewVEz0UxZjr1WYYsWpPrhyC/B/pA8Bq0fUmet2n+eR7yn0IvNzNaoBwnK6mdkzcN+se7Ez9zUgULTz2QH4g==}
engines: {node: '>=18'}
+ gopd@1.2.0:
+ resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
+ engines: {node: '>= 0.4'}
+
+ graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+
graphemer@1.4.0:
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
+ graphql@16.9.0:
+ resolution: {integrity: sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==}
+ engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0}
+
has-flag@4.0.0:
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
engines: {node: '>=8'}
+ has-property-descriptors@1.0.2:
+ resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
+
+ has-symbols@1.1.0:
+ resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
+ engines: {node: '>= 0.4'}
+
+ has-tostringtag@1.0.2:
+ resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
+ engines: {node: '>= 0.4'}
+
+ hasown@2.0.2:
+ resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
+ engines: {node: '>= 0.4'}
+
+ headers-polyfill@4.0.3:
+ resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==}
+
+ hoist-non-react-statics@3.3.2:
+ resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
+
+ husky@9.1.7:
+ resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==}
+ engines: {node: '>=18'}
+ hasBin: true
+
ignore@5.3.2:
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
engines: {node: '>= 4'}
@@ -849,18 +1806,72 @@ packages:
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
engines: {node: '>=0.8.19'}
+ indent-string@4.0.0:
+ resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
+ engines: {node: '>=8'}
+
+ inherits@2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+
+ is-arguments@1.1.1:
+ resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==}
+ engines: {node: '>= 0.4'}
+
+ is-arrayish@0.2.1:
+ resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
+
+ is-callable@1.2.7:
+ resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
+ engines: {node: '>= 0.4'}
+
+ is-core-module@2.15.1:
+ resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==}
+ engines: {node: '>= 0.4'}
+
+ is-date-object@1.1.0:
+ resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==}
+ engines: {node: '>= 0.4'}
+
+ is-docker@2.2.1:
+ resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==}
+ engines: {node: '>=8'}
+ hasBin: true
+
is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
+ is-fullwidth-code-point@3.0.0:
+ resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
+ engines: {node: '>=8'}
+
+ is-generator-function@1.0.10:
+ resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==}
+ engines: {node: '>= 0.4'}
+
is-glob@4.0.3:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
+ is-node-process@1.2.0:
+ resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==}
+
is-number@7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
+ is-regex@1.2.1:
+ resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==}
+ engines: {node: '>= 0.4'}
+
+ is-typed-array@1.1.13:
+ resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==}
+ engines: {node: '>= 0.4'}
+
+ is-wsl@2.2.0:
+ resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
+ engines: {node: '>=8'}
+
isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
@@ -871,6 +1882,10 @@ packages:
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
hasBin: true
+ jsdoc-type-pratt-parser@4.1.0:
+ resolution: {integrity: sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==}
+ engines: {node: '>=12.0.0'}
+
jsesc@3.0.2:
resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==}
engines: {node: '>=6'}
@@ -879,6 +1894,9 @@ packages:
json-buffer@3.0.1:
resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
+ json-parse-even-better-errors@2.3.1:
+ resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
+
json-schema-traverse@0.4.1:
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
@@ -890,6 +1908,13 @@ packages:
engines: {node: '>=6'}
hasBin: true
+ jsonfile@6.1.0:
+ resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
+
+ jwt-decode@4.0.0:
+ resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==}
+ engines: {node: '>=18'}
+
keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
@@ -897,20 +1922,62 @@ packages:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
+ lines-and-columns@1.2.4:
+ resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
+
locate-path@6.0.0:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'}
+ lodash-es@4.17.21:
+ resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
+
+ lodash.clonedeep@4.5.0:
+ resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==}
+
+ lodash.isequal@4.5.0:
+ resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==}
+
lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
+ lodash@4.17.21:
+ resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
+
loose-envify@1.4.0:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
+ loupe@3.1.2:
+ resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==}
+
+ lower-case@2.0.2:
+ resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
+
lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
+ lz-string@1.5.0:
+ resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==}
+ hasBin: true
+
+ magic-string@0.27.0:
+ resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==}
+ engines: {node: '>=12'}
+
+ magic-string@0.30.14:
+ resolution: {integrity: sha512-5c99P1WKTed11ZC0HMJOj6CDIue6F8ySu+bJL+85q1zBEIY8IklrJ1eiKC2NDRh3Ct3FcvmJPyQHb9erXMTJNw==}
+
+ map-or-similar@1.5.0:
+ resolution: {integrity: sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==}
+
+ math-intrinsics@1.1.0:
+ resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
+ engines: {node: '>= 0.4'}
+
+ memoizerific@1.11.3:
+ resolution: {integrity: sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==}
+
merge2@1.4.1:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
@@ -919,6 +1986,18 @@ packages:
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
engines: {node: '>=8.6'}
+ mime-db@1.52.0:
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@2.1.35:
+ resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+ engines: {node: '>= 0.6'}
+
+ min-indent@1.0.1:
+ resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
+ engines: {node: '>=4'}
+
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
@@ -926,9 +2005,26 @@ packages:
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
engines: {node: '>=16 || 14 >=14.17'}
+ minimist@1.2.8:
+ resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+ msw@2.6.8:
+ resolution: {integrity: sha512-nxXxnH6WALZ9a7rsQp4HU2AaD4iGAiouMmE/MY4al7pXTibgA6OZOuKhmN2WBIM6w9qMKwRtX8p2iOb45B2M/Q==}
+ engines: {node: '>=18'}
+ hasBin: true
+ peerDependencies:
+ typescript: '>= 4.8.x'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ mute-stream@2.0.0:
+ resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==}
+ engines: {node: ^18.17.0 || >=20.5.0}
+
nanoid@3.3.8:
resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@@ -937,13 +2033,31 @@ packages:
natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+ no-case@3.0.4:
+ resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
+
node-releases@2.0.18:
resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==}
+ object-is@1.1.6:
+ resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==}
+ engines: {node: '>= 0.4'}
+
+ object-keys@1.1.1:
+ resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
+ engines: {node: '>= 0.4'}
+
+ open@8.4.2:
+ resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==}
+ engines: {node: '>=12'}
+
optionator@0.9.4:
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
engines: {node: '>= 0.8.0'}
+ outvariant@1.4.3:
+ resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==}
+
p-limit@3.1.0:
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
engines: {node: '>=10'}
@@ -952,10 +2066,20 @@ packages:
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
engines: {node: '>=10'}
+ parchment@1.1.4:
+ resolution: {integrity: sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==}
+
+ parchment@3.0.0:
+ resolution: {integrity: sha512-HUrJFQ/StvgmXRcQ1ftY6VEZUq3jA2t9ncFN4F84J/vN0/FPpQF+8FKXb3l6fLces6q0uOHj6NJn+2xvZnxO6A==}
+
parent-module@1.0.1:
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
engines: {node: '>=6'}
+ parse-json@5.2.0:
+ resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
+ engines: {node: '>=8'}
+
path-exists@4.0.0:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'}
@@ -964,6 +2088,23 @@ packages:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
+ path-parse@1.0.7:
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+
+ path-to-regexp@6.3.0:
+ resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==}
+
+ path-type@4.0.0:
+ resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
+ engines: {node: '>=8'}
+
+ pathe@1.1.2:
+ resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
+
+ pathval@2.0.0:
+ resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==}
+ engines: {node: '>= 14.16'}
+
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
@@ -971,6 +2112,18 @@ packages:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
+ picomatch@4.0.2:
+ resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
+ engines: {node: '>=12'}
+
+ polished@4.3.1:
+ resolution: {integrity: sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==}
+ engines: {node: '>=10'}
+
+ possible-typed-array-names@1.0.0:
+ resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
+ engines: {node: '>= 0.4'}
+
postcss-value-parser@4.2.0:
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
@@ -986,18 +2139,83 @@ packages:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'}
+ pretty-format@27.5.1:
+ resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==}
+ engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+
+ process@0.11.10:
+ resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
+ engines: {node: '>= 0.6.0'}
+
+ proxy-from-env@1.1.0:
+ resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
+
+ psl@1.15.0:
+ resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==}
+
punycode@2.3.1:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'}
+ querystringify@2.2.0:
+ resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==}
+
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+ quill-delta@3.6.3:
+ resolution: {integrity: sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==}
+ engines: {node: '>=0.10'}
+
+ quill-delta@5.1.0:
+ resolution: {integrity: sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==}
+ engines: {node: '>= 12.0.0'}
+
+ quill@1.3.7:
+ resolution: {integrity: sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==}
+
+ quill@2.0.3:
+ resolution: {integrity: sha512-xEYQBqfYx/sfb33VJiKnSJp8ehloavImQ2A6564GAbqG55PGw1dAWUn1MUbQB62t0azawUS2CZZhWCjO8gRvTw==}
+ engines: {npm: '>=8.2.3'}
+
+ react-confetti@6.1.0:
+ resolution: {integrity: sha512-7Ypx4vz0+g8ECVxr88W9zhcQpbeujJAVqL14ZnXJ3I23mOI9/oBVTQ3dkJhUmB0D6XOtCZEM6N0Gm9PMngkORw==}
+ engines: {node: '>=10.18'}
+ peerDependencies:
+ react: ^16.3.0 || ^17.0.1 || ^18.0.0
+
+ react-docgen-typescript@2.2.2:
+ resolution: {integrity: sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg==}
+ peerDependencies:
+ typescript: '>= 4.3.x'
+
+ react-docgen@7.1.0:
+ resolution: {integrity: sha512-APPU8HB2uZnpl6Vt/+0AFoVYgSRtfiP6FLrZgPPTDmqSb2R4qZRbgd0A3VzIFxDt5e+Fozjx79WjLWnF69DK8g==}
+ engines: {node: '>=16.14.0'}
+
react-dom@18.3.1:
resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==}
peerDependencies:
react: ^18.3.1
+ react-hook-form@7.54.1:
+ resolution: {integrity: sha512-PUNzFwQeQ5oHiiTUO7GO/EJXGEtuun2Y1A59rLnZBBj+vNEOWt/3ERTiG1/zt7dVeJEM+4vDX/7XQ/qanuvPMg==}
+ engines: {node: '>=18.0.0'}
+ peerDependencies:
+ react: ^16.8.0 || ^17 || ^18 || ^19
+
+ react-is@16.13.1:
+ resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
+
+ react-is@17.0.2:
+ resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
+
+ react-quill@2.0.0:
+ resolution: {integrity: sha512-4qQtv1FtCfLgoD3PXAur5RyxuUbPXQGOHgTlFie3jtxp43mXDtzCKaOgQ3mLyZfi1PUlyjycfivKelFhy13QUg==}
+ peerDependencies:
+ react: ^16 || ^17 || ^18
+ react-dom: ^16 || ^17 || ^18
+
react-redux@9.1.2:
resolution: {integrity: sha512-0OA4dhM1W48l3uzmv6B7TXPCGmokUU4p1M44DGN2/D9a1FjVPukVjER1PcPX97jIg6aUeLq1XJo1IpfbgULn0w==}
peerDependencies:
@@ -1028,14 +2246,48 @@ packages:
resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
engines: {node: '>=0.10.0'}
+ recast@0.23.9:
+ resolution: {integrity: sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==}
+ engines: {node: '>= 4'}
+
+ redent@3.0.0:
+ resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==}
+ engines: {node: '>=8'}
+
+ redux-persist@6.0.0:
+ resolution: {integrity: sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==}
+ peerDependencies:
+ react: '>=16'
+ redux: '>4.0.0'
+ peerDependenciesMeta:
+ react:
+ optional: true
+
redux-thunk@3.1.0:
resolution: {integrity: sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==}
peerDependencies:
redux: ^5.0.0
+ redux@4.2.1:
+ resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==}
+
redux@5.0.1:
resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==}
+ regenerator-runtime@0.14.1:
+ resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
+
+ regexp.prototype.flags@1.5.3:
+ resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==}
+ engines: {node: '>= 0.4'}
+
+ require-directory@2.1.1:
+ resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
+ engines: {node: '>=0.10.0'}
+
+ requires-port@1.0.0:
+ resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
+
reselect@5.1.1:
resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==}
@@ -1043,6 +2295,10 @@ packages:
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
engines: {node: '>=4'}
+ resolve@1.22.8:
+ resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
+ hasBin: true
+
reusify@1.0.4:
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
@@ -1070,6 +2326,14 @@ packages:
set-cookie-parser@2.7.1:
resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==}
+ set-function-length@1.2.2:
+ resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
+ engines: {node: '>= 0.4'}
+
+ set-function-name@2.0.2:
+ resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
+ engines: {node: '>= 0.4'}
+
shallowequal@1.1.0:
resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==}
@@ -1081,10 +2345,70 @@ packages:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
+ siginfo@2.0.0:
+ resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
+
+ signal-exit@4.1.0:
+ resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
+ engines: {node: '>=14'}
+
+ snake-case@3.0.4:
+ resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==}
+
source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
+ source-map@0.6.1:
+ resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
+ engines: {node: '>=0.10.0'}
+
+ stackback@0.0.2:
+ resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
+
+ statuses@2.0.1:
+ resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
+ engines: {node: '>= 0.8'}
+
+ std-env@3.8.0:
+ resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==}
+
+ storybook@8.4.7:
+ resolution: {integrity: sha512-RP/nMJxiWyFc8EVMH5gp20ID032Wvk+Yr3lmKidoegto5Iy+2dVQnUoElZb2zpbVXNHWakGuAkfI0dY1Hfp/vw==}
+ hasBin: true
+ peerDependencies:
+ prettier: ^2 || ^3
+ peerDependenciesMeta:
+ prettier:
+ optional: true
+
+ strict-event-emitter@0.5.1:
+ resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==}
+
+ string-width@4.2.3:
+ resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
+ engines: {node: '>=8'}
+
+ strip-ansi@6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+
+ strip-ansi@7.1.0:
+ resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
+ engines: {node: '>=12'}
+
+ strip-bom@3.0.0:
+ resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
+ engines: {node: '>=4'}
+
+ strip-indent@3.0.0:
+ resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
+ engines: {node: '>=8'}
+
+ strip-indent@4.0.0:
+ resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==}
+ engines: {node: '>=12'}
+
strip-json-comments@3.1.1:
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
engines: {node: '>=8'}
@@ -1103,26 +2427,81 @@ packages:
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
engines: {node: '>=8'}
+ supports-preserve-symlinks-flag@1.0.0:
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+ engines: {node: '>= 0.4'}
+
+ svg-parser@2.0.4:
+ resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==}
+
+ tiny-invariant@1.3.3:
+ resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==}
+
+ tinybench@2.9.0:
+ resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
+
+ tinyexec@0.3.1:
+ resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==}
+
+ tinypool@1.0.2:
+ resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+
+ tinyrainbow@1.2.0:
+ resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==}
+ engines: {node: '>=14.0.0'}
+
+ tinyspy@3.0.2:
+ resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==}
+ engines: {node: '>=14.0.0'}
+
to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
+ tough-cookie@4.1.4:
+ resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==}
+ engines: {node: '>=6'}
+
ts-api-utils@1.4.3:
resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==}
engines: {node: '>=16'}
peerDependencies:
typescript: '>=4.2.0'
+ ts-dedent@2.2.0:
+ resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==}
+ engines: {node: '>=6.10'}
+
+ tsconfig-paths@4.2.0:
+ resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==}
+ engines: {node: '>=6'}
+
tslib@2.6.2:
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
turbo-stream@2.4.0:
resolution: {integrity: sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==}
+ tween-functions@1.2.0:
+ resolution: {integrity: sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA==}
+
type-check@0.4.0:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'}
+ type-fest@0.21.3:
+ resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
+ engines: {node: '>=10'}
+
+ type-fest@2.19.0:
+ resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
+ engines: {node: '>=12.20'}
+
+ type-fest@4.30.0:
+ resolution: {integrity: sha512-G6zXWS1dLj6eagy6sVhOMQiLtJdxQBHIA9Z6HFUNLOlr6MFOgzV8wvmidtPONfPtEUv0uZsy77XJNzTAfwPDaA==}
+ engines: {node: '>=16'}
+
typescript-eslint@8.17.0:
resolution: {integrity: sha512-409VXvFd/f1br1DCbuKNFqQpXICoTB+V51afcwG1pn1a3Cp92MqAUges3YjwEdQ0cMUoCIodjVDAYzyD8h3SYA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -1138,20 +2517,86 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
- update-browserslist-db@1.1.1:
- resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==}
- hasBin: true
+ undici-types@6.20.0:
+ resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
+
+ universalify@0.2.0:
+ resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==}
+ engines: {node: '>= 4.0.0'}
+
+ universalify@2.0.1:
+ resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
+ engines: {node: '>= 10.0.0'}
+
+ unplugin@1.16.0:
+ resolution: {integrity: sha512-5liCNPuJW8dqh3+DM6uNM2EI3MLLpCKp/KY+9pB5M2S2SR2qvvDHhKgBOaTWEbZTAws3CXfB0rKTIolWKL05VQ==}
+ engines: {node: '>=14.0.0'}
+
+ update-browserslist-db@1.1.1:
+ resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==}
+ hasBin: true
peerDependencies:
browserslist: '>= 4.21.0'
uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+ url-parse@1.5.10:
+ resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==}
+
use-sync-external-store@1.4.0:
resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ util@0.12.5:
+ resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==}
+
+ uuid@9.0.1:
+ resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
+ hasBin: true
+
+ vite-node@2.1.8:
+ resolution: {integrity: sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+ hasBin: true
+
+ vite-plugin-svgr@4.3.0:
+ resolution: {integrity: sha512-Jy9qLB2/PyWklpYy0xk0UU3TlU0t2UMpJXZvf+hWII1lAmRHrOUKi11Uw8N3rxoNk7atZNYO3pR3vI1f7oi+6w==}
+ peerDependencies:
+ vite: '>=2.6.0'
+
+ vite@5.4.11:
+ resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^18.0.0 || >=20.0.0
+ less: '*'
+ lightningcss: ^1.21.0
+ sass: '*'
+ sass-embedded: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.4.0
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+
vite@6.0.3:
resolution: {integrity: sha512-Cmuo5P0ENTN6HxLSo6IHsjCLn/81Vgrp81oaiFFMRa8gGDj5xEjIcEpf2ZymZtZR8oU0P2JX5WuUp/rlXcHkAw==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
@@ -1192,24 +2637,99 @@ packages:
yaml:
optional: true
+ vitest@2.1.8:
+ resolution: {integrity: sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+ hasBin: true
+ peerDependencies:
+ '@edge-runtime/vm': '*'
+ '@types/node': ^18.0.0 || >=20.0.0
+ '@vitest/browser': 2.1.8
+ '@vitest/ui': 2.1.8
+ happy-dom: '*'
+ jsdom: '*'
+ peerDependenciesMeta:
+ '@edge-runtime/vm':
+ optional: true
+ '@types/node':
+ optional: true
+ '@vitest/browser':
+ optional: true
+ '@vitest/ui':
+ optional: true
+ happy-dom:
+ optional: true
+ jsdom:
+ optional: true
+
+ webpack-virtual-modules@0.6.2:
+ resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
+
+ which-typed-array@1.1.16:
+ resolution: {integrity: sha512-g+N+GAWiRj66DngFwHvISJd+ITsyphZvD1vChfVg6cEdnzy53GzB3oy0fUNlvhz7H7+MiqhYr26qxQShCpKTTQ==}
+ engines: {node: '>= 0.4'}
+
which@2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'}
hasBin: true
+ why-is-node-running@2.3.0:
+ resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
+ engines: {node: '>=8'}
+ hasBin: true
+
word-wrap@1.2.5:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
engines: {node: '>=0.10.0'}
+ wrap-ansi@6.2.0:
+ resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
+ engines: {node: '>=8'}
+
+ wrap-ansi@7.0.0:
+ resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
+ engines: {node: '>=10'}
+
+ ws@8.18.0:
+ resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==}
+ engines: {node: '>=10.0.0'}
+ peerDependencies:
+ bufferutil: ^4.0.1
+ utf-8-validate: '>=5.0.2'
+ peerDependenciesMeta:
+ bufferutil:
+ optional: true
+ utf-8-validate:
+ optional: true
+
+ y18n@5.0.8:
+ resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
+ engines: {node: '>=10'}
+
yallist@3.1.1:
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
+ yargs-parser@21.1.1:
+ resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
+ engines: {node: '>=12'}
+
+ yargs@17.7.2:
+ resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
+ engines: {node: '>=12'}
+
yocto-queue@0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
+ yoctocolors-cjs@2.1.2:
+ resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==}
+ engines: {node: '>=18'}
+
snapshots:
+ '@adobe/css-tools@4.4.1': {}
+
'@ampproject/remapping@2.3.0':
dependencies:
'@jridgewell/gen-mapping': 0.3.5
@@ -1302,6 +2822,10 @@ snapshots:
'@babel/core': 7.26.0
'@babel/helper-plugin-utils': 7.25.9
+ '@babel/runtime@7.26.0':
+ dependencies:
+ regenerator-runtime: 0.14.1
+
'@babel/template@7.25.9':
dependencies:
'@babel/code-frame': 7.26.2
@@ -1325,6 +2849,32 @@ snapshots:
'@babel/helper-string-parser': 7.25.9
'@babel/helper-validator-identifier': 7.25.9
+ '@bundled-es-modules/cookie@2.0.1':
+ dependencies:
+ cookie: 0.7.2
+
+ '@bundled-es-modules/statuses@1.0.1':
+ dependencies:
+ statuses: 2.0.1
+
+ '@bundled-es-modules/tough-cookie@0.1.6':
+ dependencies:
+ '@types/tough-cookie': 4.0.5
+ tough-cookie: 4.1.4
+
+ '@chromatic-com/storybook@3.2.2(react@18.3.1)(storybook@8.4.7)':
+ dependencies:
+ chromatic: 11.20.0
+ filesize: 10.1.6
+ jsonfile: 6.1.0
+ react-confetti: 6.1.0(react@18.3.1)
+ storybook: 8.4.7
+ strip-ansi: 7.1.0
+ transitivePeerDependencies:
+ - '@chromatic-com/cypress'
+ - '@chromatic-com/playwright'
+ - react
+
'@emotion/is-prop-valid@1.2.2':
dependencies:
'@emotion/memoize': 0.8.1
@@ -1333,75 +2883,144 @@ snapshots:
'@emotion/unitless@0.8.1': {}
+ '@esbuild/aix-ppc64@0.21.5':
+ optional: true
+
'@esbuild/aix-ppc64@0.24.0':
optional: true
+ '@esbuild/android-arm64@0.21.5':
+ optional: true
+
'@esbuild/android-arm64@0.24.0':
optional: true
+ '@esbuild/android-arm@0.21.5':
+ optional: true
+
'@esbuild/android-arm@0.24.0':
optional: true
+ '@esbuild/android-x64@0.21.5':
+ optional: true
+
'@esbuild/android-x64@0.24.0':
optional: true
+ '@esbuild/darwin-arm64@0.21.5':
+ optional: true
+
'@esbuild/darwin-arm64@0.24.0':
optional: true
+ '@esbuild/darwin-x64@0.21.5':
+ optional: true
+
'@esbuild/darwin-x64@0.24.0':
optional: true
+ '@esbuild/freebsd-arm64@0.21.5':
+ optional: true
+
'@esbuild/freebsd-arm64@0.24.0':
optional: true
+ '@esbuild/freebsd-x64@0.21.5':
+ optional: true
+
'@esbuild/freebsd-x64@0.24.0':
optional: true
+ '@esbuild/linux-arm64@0.21.5':
+ optional: true
+
'@esbuild/linux-arm64@0.24.0':
optional: true
+ '@esbuild/linux-arm@0.21.5':
+ optional: true
+
'@esbuild/linux-arm@0.24.0':
optional: true
+ '@esbuild/linux-ia32@0.21.5':
+ optional: true
+
'@esbuild/linux-ia32@0.24.0':
optional: true
+ '@esbuild/linux-loong64@0.21.5':
+ optional: true
+
'@esbuild/linux-loong64@0.24.0':
optional: true
+ '@esbuild/linux-mips64el@0.21.5':
+ optional: true
+
'@esbuild/linux-mips64el@0.24.0':
optional: true
+ '@esbuild/linux-ppc64@0.21.5':
+ optional: true
+
'@esbuild/linux-ppc64@0.24.0':
optional: true
+ '@esbuild/linux-riscv64@0.21.5':
+ optional: true
+
'@esbuild/linux-riscv64@0.24.0':
optional: true
+ '@esbuild/linux-s390x@0.21.5':
+ optional: true
+
'@esbuild/linux-s390x@0.24.0':
optional: true
+ '@esbuild/linux-x64@0.21.5':
+ optional: true
+
'@esbuild/linux-x64@0.24.0':
optional: true
+ '@esbuild/netbsd-x64@0.21.5':
+ optional: true
+
'@esbuild/netbsd-x64@0.24.0':
optional: true
'@esbuild/openbsd-arm64@0.24.0':
optional: true
+ '@esbuild/openbsd-x64@0.21.5':
+ optional: true
+
'@esbuild/openbsd-x64@0.24.0':
optional: true
+ '@esbuild/sunos-x64@0.21.5':
+ optional: true
+
'@esbuild/sunos-x64@0.24.0':
optional: true
+ '@esbuild/win32-arm64@0.21.5':
+ optional: true
+
'@esbuild/win32-arm64@0.24.0':
optional: true
+ '@esbuild/win32-ia32@0.21.5':
+ optional: true
+
'@esbuild/win32-ia32@0.24.0':
optional: true
+ '@esbuild/win32-x64@0.21.5':
+ optional: true
+
'@esbuild/win32-x64@0.24.0':
optional: true
@@ -1446,6 +3065,10 @@ snapshots:
dependencies:
levn: 0.4.1
+ '@heroicons/react@2.2.0(react@18.3.1)':
+ dependencies:
+ react: 18.3.1
+
'@humanfs/core@0.19.1': {}
'@humanfs/node@0.16.6':
@@ -1459,6 +3082,40 @@ snapshots:
'@humanwhocodes/retry@0.4.1': {}
+ '@inquirer/confirm@5.1.0(@types/node@22.10.2)':
+ dependencies:
+ '@inquirer/core': 10.1.1(@types/node@22.10.2)
+ '@inquirer/type': 3.0.1(@types/node@22.10.2)
+ '@types/node': 22.10.2
+
+ '@inquirer/core@10.1.1(@types/node@22.10.2)':
+ dependencies:
+ '@inquirer/figures': 1.0.8
+ '@inquirer/type': 3.0.1(@types/node@22.10.2)
+ ansi-escapes: 4.3.2
+ cli-width: 4.1.0
+ mute-stream: 2.0.0
+ signal-exit: 4.1.0
+ strip-ansi: 6.0.1
+ wrap-ansi: 6.2.0
+ yoctocolors-cjs: 2.1.2
+ transitivePeerDependencies:
+ - '@types/node'
+
+ '@inquirer/figures@1.0.8': {}
+
+ '@inquirer/type@3.0.1(@types/node@22.10.2)':
+ dependencies:
+ '@types/node': 22.10.2
+
+ '@joshwooding/vite-plugin-react-docgen-typescript@0.4.2(typescript@5.6.3)(vite@6.0.3(@types/node@22.10.2))':
+ dependencies:
+ magic-string: 0.27.0
+ react-docgen-typescript: 2.2.2(typescript@5.6.3)
+ vite: 6.0.3(@types/node@22.10.2)
+ optionalDependencies:
+ typescript: 5.6.3
+
'@jridgewell/gen-mapping@0.3.5':
dependencies:
'@jridgewell/set-array': 1.2.1
@@ -1476,6 +3133,21 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.0
+ '@mdx-js/react@3.1.0(@types/react@18.3.14)(react@18.3.1)':
+ dependencies:
+ '@types/mdx': 2.0.13
+ '@types/react': 18.3.14
+ react: 18.3.1
+
+ '@mswjs/interceptors@0.37.3':
+ dependencies:
+ '@open-draft/deferred-promise': 2.2.0
+ '@open-draft/logger': 0.3.0
+ '@open-draft/until': 2.1.0
+ is-node-process: 1.2.0
+ outvariant: 1.4.3
+ strict-event-emitter: 0.5.1
+
'@nodelib/fs.scandir@2.1.5':
dependencies:
'@nodelib/fs.stat': 2.0.5
@@ -1488,6 +3160,15 @@ snapshots:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.17.1
+ '@open-draft/deferred-promise@2.2.0': {}
+
+ '@open-draft/logger@0.3.0':
+ dependencies:
+ is-node-process: 1.2.0
+ outvariant: 1.4.3
+
+ '@open-draft/until@2.1.0': {}
+
'@reduxjs/toolkit@2.4.0(react-redux@9.1.2(@types/react@18.3.14)(react@18.3.1)(redux@5.0.1))(react@18.3.1)':
dependencies:
immer: 10.1.1
@@ -1498,6 +3179,14 @@ snapshots:
react: 18.3.1
react-redux: 9.1.2(@types/react@18.3.14)(react@18.3.1)(redux@5.0.1)
+ '@rollup/pluginutils@5.1.3(rollup@4.28.0)':
+ dependencies:
+ '@types/estree': 1.0.6
+ estree-walker: 2.0.2
+ picomatch: 4.0.2
+ optionalDependencies:
+ rollup: 4.28.0
+
'@rollup/rollup-android-arm-eabi@4.28.0':
optional: true
@@ -1552,112 +3241,482 @@ snapshots:
'@rollup/rollup-win32-x64-msvc@4.28.0':
optional: true
- '@tanstack/query-core@5.62.2': {}
-
- '@tanstack/react-query@5.62.2(react@18.3.1)':
+ '@storybook/addon-actions@8.4.7(storybook@8.4.7)':
dependencies:
- '@tanstack/query-core': 5.62.2
- react: 18.3.1
+ '@storybook/global': 5.0.0
+ '@types/uuid': 9.0.8
+ dequal: 2.0.3
+ polished: 4.3.1
+ storybook: 8.4.7
+ uuid: 9.0.1
+
+ '@storybook/addon-backgrounds@8.4.7(storybook@8.4.7)':
+ dependencies:
+ '@storybook/global': 5.0.0
+ memoizerific: 1.11.3
+ storybook: 8.4.7
+ ts-dedent: 2.2.0
- '@types/babel__core@7.20.5':
+ '@storybook/addon-controls@8.4.7(storybook@8.4.7)':
dependencies:
- '@babel/parser': 7.26.3
- '@babel/types': 7.26.3
- '@types/babel__generator': 7.6.8
- '@types/babel__template': 7.4.4
- '@types/babel__traverse': 7.20.6
+ '@storybook/global': 5.0.0
+ dequal: 2.0.3
+ storybook: 8.4.7
+ ts-dedent: 2.2.0
- '@types/babel__generator@7.6.8':
+ '@storybook/addon-docs@8.4.7(@types/react@18.3.14)(storybook@8.4.7)':
dependencies:
- '@babel/types': 7.26.3
+ '@mdx-js/react': 3.1.0(@types/react@18.3.14)(react@18.3.1)
+ '@storybook/blocks': 8.4.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7)
+ '@storybook/csf-plugin': 8.4.7(storybook@8.4.7)
+ '@storybook/react-dom-shim': 8.4.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7)
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ storybook: 8.4.7
+ ts-dedent: 2.2.0
+ transitivePeerDependencies:
+ - '@types/react'
- '@types/babel__template@7.4.4':
+ '@storybook/addon-essentials@8.4.7(@types/react@18.3.14)(storybook@8.4.7)':
dependencies:
- '@babel/parser': 7.26.3
- '@babel/types': 7.26.3
+ '@storybook/addon-actions': 8.4.7(storybook@8.4.7)
+ '@storybook/addon-backgrounds': 8.4.7(storybook@8.4.7)
+ '@storybook/addon-controls': 8.4.7(storybook@8.4.7)
+ '@storybook/addon-docs': 8.4.7(@types/react@18.3.14)(storybook@8.4.7)
+ '@storybook/addon-highlight': 8.4.7(storybook@8.4.7)
+ '@storybook/addon-measure': 8.4.7(storybook@8.4.7)
+ '@storybook/addon-outline': 8.4.7(storybook@8.4.7)
+ '@storybook/addon-toolbars': 8.4.7(storybook@8.4.7)
+ '@storybook/addon-viewport': 8.4.7(storybook@8.4.7)
+ storybook: 8.4.7
+ ts-dedent: 2.2.0
+ transitivePeerDependencies:
+ - '@types/react'
- '@types/babel__traverse@7.20.6':
+ '@storybook/addon-highlight@8.4.7(storybook@8.4.7)':
dependencies:
- '@babel/types': 7.26.3
+ '@storybook/global': 5.0.0
+ storybook: 8.4.7
- '@types/cookie@0.6.0': {}
+ '@storybook/addon-interactions@8.4.7(storybook@8.4.7)':
+ dependencies:
+ '@storybook/global': 5.0.0
+ '@storybook/instrumenter': 8.4.7(storybook@8.4.7)
+ '@storybook/test': 8.4.7(storybook@8.4.7)
+ polished: 4.3.1
+ storybook: 8.4.7
+ ts-dedent: 2.2.0
+
+ '@storybook/addon-measure@8.4.7(storybook@8.4.7)':
+ dependencies:
+ '@storybook/global': 5.0.0
+ storybook: 8.4.7
+ tiny-invariant: 1.3.3
- '@types/estree@1.0.6': {}
+ '@storybook/addon-onboarding@8.4.7(react@18.3.1)(storybook@8.4.7)':
+ dependencies:
+ react-confetti: 6.1.0(react@18.3.1)
+ storybook: 8.4.7
+ transitivePeerDependencies:
+ - react
- '@types/json-schema@7.0.15': {}
+ '@storybook/addon-outline@8.4.7(storybook@8.4.7)':
+ dependencies:
+ '@storybook/global': 5.0.0
+ storybook: 8.4.7
+ ts-dedent: 2.2.0
- '@types/prop-types@15.7.14': {}
+ '@storybook/addon-toolbars@8.4.7(storybook@8.4.7)':
+ dependencies:
+ storybook: 8.4.7
- '@types/react-dom@18.3.2':
+ '@storybook/addon-viewport@8.4.7(storybook@8.4.7)':
dependencies:
- '@types/react': 18.3.14
+ memoizerific: 1.11.3
+ storybook: 8.4.7
- '@types/react@18.3.14':
+ '@storybook/blocks@8.4.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7)':
dependencies:
- '@types/prop-types': 15.7.14
- csstype: 3.1.3
+ '@storybook/csf': 0.1.12
+ '@storybook/icons': 1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ storybook: 8.4.7
+ ts-dedent: 2.2.0
+ optionalDependencies:
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
- '@types/stylis@4.2.5': {}
+ '@storybook/builder-vite@8.4.7(storybook@8.4.7)(vite@6.0.3(@types/node@22.10.2))':
+ dependencies:
+ '@storybook/csf-plugin': 8.4.7(storybook@8.4.7)
+ browser-assert: 1.2.1
+ storybook: 8.4.7
+ ts-dedent: 2.2.0
+ vite: 6.0.3(@types/node@22.10.2)
- '@types/use-sync-external-store@0.0.3': {}
+ '@storybook/components@8.4.7(storybook@8.4.7)':
+ dependencies:
+ storybook: 8.4.7
- '@typescript-eslint/eslint-plugin@8.17.0(@typescript-eslint/parser@8.17.0(eslint@9.16.0)(typescript@5.6.3))(eslint@9.16.0)(typescript@5.6.3)':
+ '@storybook/core@8.4.7':
dependencies:
- '@eslint-community/regexpp': 4.12.1
- '@typescript-eslint/parser': 8.17.0(eslint@9.16.0)(typescript@5.6.3)
- '@typescript-eslint/scope-manager': 8.17.0
- '@typescript-eslint/type-utils': 8.17.0(eslint@9.16.0)(typescript@5.6.3)
- '@typescript-eslint/utils': 8.17.0(eslint@9.16.0)(typescript@5.6.3)
- '@typescript-eslint/visitor-keys': 8.17.0
- eslint: 9.16.0
- graphemer: 1.4.0
- ignore: 5.3.2
- natural-compare: 1.4.0
- ts-api-utils: 1.4.3(typescript@5.6.3)
- optionalDependencies:
- typescript: 5.6.3
+ '@storybook/csf': 0.1.12
+ better-opn: 3.0.2
+ browser-assert: 1.2.1
+ esbuild: 0.24.0
+ esbuild-register: 3.6.0(esbuild@0.24.0)
+ jsdoc-type-pratt-parser: 4.1.0
+ process: 0.11.10
+ recast: 0.23.9
+ semver: 7.6.3
+ util: 0.12.5
+ ws: 8.18.0
transitivePeerDependencies:
+ - bufferutil
- supports-color
+ - utf-8-validate
- '@typescript-eslint/parser@8.17.0(eslint@9.16.0)(typescript@5.6.3)':
+ '@storybook/csf-plugin@8.4.7(storybook@8.4.7)':
dependencies:
- '@typescript-eslint/scope-manager': 8.17.0
- '@typescript-eslint/types': 8.17.0
- '@typescript-eslint/typescript-estree': 8.17.0(typescript@5.6.3)
- '@typescript-eslint/visitor-keys': 8.17.0
- debug: 4.3.7
- eslint: 9.16.0
- optionalDependencies:
- typescript: 5.6.3
- transitivePeerDependencies:
- - supports-color
+ storybook: 8.4.7
+ unplugin: 1.16.0
- '@typescript-eslint/scope-manager@8.17.0':
+ '@storybook/csf@0.1.12':
dependencies:
- '@typescript-eslint/types': 8.17.0
- '@typescript-eslint/visitor-keys': 8.17.0
+ type-fest: 2.19.0
- '@typescript-eslint/type-utils@8.17.0(eslint@9.16.0)(typescript@5.6.3)':
+ '@storybook/global@5.0.0': {}
+
+ '@storybook/icons@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
- '@typescript-eslint/typescript-estree': 8.17.0(typescript@5.6.3)
- '@typescript-eslint/utils': 8.17.0(eslint@9.16.0)(typescript@5.6.3)
- debug: 4.3.7
- eslint: 9.16.0
- ts-api-utils: 1.4.3(typescript@5.6.3)
- optionalDependencies:
- typescript: 5.6.3
- transitivePeerDependencies:
- - supports-color
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
- '@typescript-eslint/types@8.17.0': {}
+ '@storybook/instrumenter@8.4.7(storybook@8.4.7)':
+ dependencies:
+ '@storybook/global': 5.0.0
+ '@vitest/utils': 2.1.8
+ storybook: 8.4.7
- '@typescript-eslint/typescript-estree@8.17.0(typescript@5.6.3)':
+ '@storybook/manager-api@8.4.7(storybook@8.4.7)':
dependencies:
- '@typescript-eslint/types': 8.17.0
- '@typescript-eslint/visitor-keys': 8.17.0
- debug: 4.3.7
- fast-glob: 3.3.2
- is-glob: 4.0.3
+ storybook: 8.4.7
+
+ '@storybook/preview-api@8.4.7(storybook@8.4.7)':
+ dependencies:
+ storybook: 8.4.7
+
+ '@storybook/react-dom-shim@8.4.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7)':
+ dependencies:
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ storybook: 8.4.7
+
+ '@storybook/react-vite@8.4.7(@storybook/test@8.4.7(storybook@8.4.7))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.28.0)(storybook@8.4.7)(typescript@5.6.3)(vite@6.0.3(@types/node@22.10.2))':
+ dependencies:
+ '@joshwooding/vite-plugin-react-docgen-typescript': 0.4.2(typescript@5.6.3)(vite@6.0.3(@types/node@22.10.2))
+ '@rollup/pluginutils': 5.1.3(rollup@4.28.0)
+ '@storybook/builder-vite': 8.4.7(storybook@8.4.7)(vite@6.0.3(@types/node@22.10.2))
+ '@storybook/react': 8.4.7(@storybook/test@8.4.7(storybook@8.4.7))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7)(typescript@5.6.3)
+ find-up: 5.0.0
+ magic-string: 0.30.14
+ react: 18.3.1
+ react-docgen: 7.1.0
+ react-dom: 18.3.1(react@18.3.1)
+ resolve: 1.22.8
+ storybook: 8.4.7
+ tsconfig-paths: 4.2.0
+ vite: 6.0.3(@types/node@22.10.2)
+ transitivePeerDependencies:
+ - '@storybook/test'
+ - rollup
+ - supports-color
+ - typescript
+
+ '@storybook/react@8.4.7(@storybook/test@8.4.7(storybook@8.4.7))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7)(typescript@5.6.3)':
+ dependencies:
+ '@storybook/components': 8.4.7(storybook@8.4.7)
+ '@storybook/global': 5.0.0
+ '@storybook/manager-api': 8.4.7(storybook@8.4.7)
+ '@storybook/preview-api': 8.4.7(storybook@8.4.7)
+ '@storybook/react-dom-shim': 8.4.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7)
+ '@storybook/theming': 8.4.7(storybook@8.4.7)
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ storybook: 8.4.7
+ optionalDependencies:
+ '@storybook/test': 8.4.7(storybook@8.4.7)
+ typescript: 5.6.3
+
+ '@storybook/test@8.4.7(storybook@8.4.7)':
+ dependencies:
+ '@storybook/csf': 0.1.12
+ '@storybook/global': 5.0.0
+ '@storybook/instrumenter': 8.4.7(storybook@8.4.7)
+ '@testing-library/dom': 10.4.0
+ '@testing-library/jest-dom': 6.5.0
+ '@testing-library/user-event': 14.5.2(@testing-library/dom@10.4.0)
+ '@vitest/expect': 2.0.5
+ '@vitest/spy': 2.0.5
+ storybook: 8.4.7
+
+ '@storybook/theming@8.4.7(storybook@8.4.7)':
+ dependencies:
+ storybook: 8.4.7
+
+ '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.26.0)':
+ dependencies:
+ '@babel/core': 7.26.0
+
+ '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.26.0)':
+ dependencies:
+ '@babel/core': 7.26.0
+
+ '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.26.0)':
+ dependencies:
+ '@babel/core': 7.26.0
+
+ '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.26.0)':
+ dependencies:
+ '@babel/core': 7.26.0
+
+ '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.26.0)':
+ dependencies:
+ '@babel/core': 7.26.0
+
+ '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.26.0)':
+ dependencies:
+ '@babel/core': 7.26.0
+
+ '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.26.0)':
+ dependencies:
+ '@babel/core': 7.26.0
+
+ '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.26.0)':
+ dependencies:
+ '@babel/core': 7.26.0
+
+ '@svgr/babel-preset@8.1.0(@babel/core@7.26.0)':
+ dependencies:
+ '@babel/core': 7.26.0
+ '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.26.0)
+ '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.26.0)
+ '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.26.0)
+ '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.26.0)
+ '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.26.0)
+ '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.26.0)
+ '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.26.0)
+ '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.26.0)
+
+ '@svgr/core@8.1.0(typescript@5.6.3)':
+ dependencies:
+ '@babel/core': 7.26.0
+ '@svgr/babel-preset': 8.1.0(@babel/core@7.26.0)
+ camelcase: 6.3.0
+ cosmiconfig: 8.3.6(typescript@5.6.3)
+ snake-case: 3.0.4
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+
+ '@svgr/hast-util-to-babel-ast@8.0.0':
+ dependencies:
+ '@babel/types': 7.26.3
+ entities: 4.5.0
+
+ '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.6.3))':
+ dependencies:
+ '@babel/core': 7.26.0
+ '@svgr/babel-preset': 8.1.0(@babel/core@7.26.0)
+ '@svgr/core': 8.1.0(typescript@5.6.3)
+ '@svgr/hast-util-to-babel-ast': 8.0.0
+ svg-parser: 2.0.4
+ transitivePeerDependencies:
+ - supports-color
+
+ '@tanstack/query-core@5.62.2': {}
+
+ '@tanstack/react-query@5.62.2(react@18.3.1)':
+ dependencies:
+ '@tanstack/query-core': 5.62.2
+ react: 18.3.1
+
+ '@testing-library/dom@10.4.0':
+ dependencies:
+ '@babel/code-frame': 7.26.2
+ '@babel/runtime': 7.26.0
+ '@types/aria-query': 5.0.4
+ aria-query: 5.3.0
+ chalk: 4.1.2
+ dom-accessibility-api: 0.5.16
+ lz-string: 1.5.0
+ pretty-format: 27.5.1
+
+ '@testing-library/jest-dom@6.5.0':
+ dependencies:
+ '@adobe/css-tools': 4.4.1
+ aria-query: 5.3.2
+ chalk: 3.0.0
+ css.escape: 1.5.1
+ dom-accessibility-api: 0.6.3
+ lodash: 4.17.21
+ redent: 3.0.0
+
+ '@testing-library/user-event@14.5.2(@testing-library/dom@10.4.0)':
+ dependencies:
+ '@testing-library/dom': 10.4.0
+
+ '@types/aria-query@5.0.4': {}
+
+ '@types/babel__core@7.20.5':
+ dependencies:
+ '@babel/parser': 7.26.3
+ '@babel/types': 7.26.3
+ '@types/babel__generator': 7.6.8
+ '@types/babel__template': 7.4.4
+ '@types/babel__traverse': 7.20.6
+
+ '@types/babel__generator@7.6.8':
+ dependencies:
+ '@babel/types': 7.26.3
+
+ '@types/babel__template@7.4.4':
+ dependencies:
+ '@babel/parser': 7.26.3
+ '@babel/types': 7.26.3
+
+ '@types/babel__traverse@7.20.6':
+ dependencies:
+ '@babel/types': 7.26.3
+
+ '@types/cookie@0.6.0': {}
+
+ '@types/doctrine@0.0.9': {}
+
+ '@types/estree@1.0.6': {}
+
+ '@types/hoist-non-react-statics@3.3.6':
+ dependencies:
+ '@types/react': 18.3.14
+ hoist-non-react-statics: 3.3.2
+
+ '@types/json-schema@7.0.15': {}
+
+ '@types/jwt-decode@3.1.0':
+ dependencies:
+ jwt-decode: 4.0.0
+
+ '@types/mdx@2.0.13': {}
+
+ '@types/node@22.10.2':
+ dependencies:
+ undici-types: 6.20.0
+
+ '@types/prop-types@15.7.14': {}
+
+ '@types/quill@1.3.10':
+ dependencies:
+ parchment: 1.1.4
+
+ '@types/quill@2.0.14':
+ dependencies:
+ parchment: 1.1.4
+ quill-delta: 5.1.0
+
+ '@types/react-dom@18.3.2':
+ dependencies:
+ '@types/react': 18.3.14
+
+ '@types/react-redux@7.1.34':
+ dependencies:
+ '@types/hoist-non-react-statics': 3.3.6
+ '@types/react': 18.3.14
+ hoist-non-react-statics: 3.3.2
+ redux: 4.2.1
+
+ '@types/react@18.3.14':
+ dependencies:
+ '@types/prop-types': 15.7.14
+ csstype: 3.1.3
+
+ '@types/redux-persist@4.3.1(react@18.3.1)(redux@5.0.1)':
+ dependencies:
+ redux-persist: 6.0.0(react@18.3.1)(redux@5.0.1)
+ transitivePeerDependencies:
+ - react
+ - redux
+
+ '@types/resolve@1.20.6': {}
+
+ '@types/statuses@2.0.5': {}
+
+ '@types/stylis@4.2.5': {}
+
+ '@types/tough-cookie@4.0.5': {}
+
+ '@types/trusted-types@2.0.7':
+ optional: true
+
+ '@types/use-sync-external-store@0.0.3': {}
+
+ '@types/uuid@9.0.8': {}
+
+ '@typescript-eslint/eslint-plugin@8.17.0(@typescript-eslint/parser@8.17.0(eslint@9.16.0)(typescript@5.6.3))(eslint@9.16.0)(typescript@5.6.3)':
+ dependencies:
+ '@eslint-community/regexpp': 4.12.1
+ '@typescript-eslint/parser': 8.17.0(eslint@9.16.0)(typescript@5.6.3)
+ '@typescript-eslint/scope-manager': 8.17.0
+ '@typescript-eslint/type-utils': 8.17.0(eslint@9.16.0)(typescript@5.6.3)
+ '@typescript-eslint/utils': 8.17.0(eslint@9.16.0)(typescript@5.6.3)
+ '@typescript-eslint/visitor-keys': 8.17.0
+ eslint: 9.16.0
+ graphemer: 1.4.0
+ ignore: 5.3.2
+ natural-compare: 1.4.0
+ ts-api-utils: 1.4.3(typescript@5.6.3)
+ optionalDependencies:
+ typescript: 5.6.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/parser@8.17.0(eslint@9.16.0)(typescript@5.6.3)':
+ dependencies:
+ '@typescript-eslint/scope-manager': 8.17.0
+ '@typescript-eslint/types': 8.17.0
+ '@typescript-eslint/typescript-estree': 8.17.0(typescript@5.6.3)
+ '@typescript-eslint/visitor-keys': 8.17.0
+ debug: 4.3.7
+ eslint: 9.16.0
+ optionalDependencies:
+ typescript: 5.6.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/scope-manager@8.17.0':
+ dependencies:
+ '@typescript-eslint/types': 8.17.0
+ '@typescript-eslint/visitor-keys': 8.17.0
+
+ '@typescript-eslint/type-utils@8.17.0(eslint@9.16.0)(typescript@5.6.3)':
+ dependencies:
+ '@typescript-eslint/typescript-estree': 8.17.0(typescript@5.6.3)
+ '@typescript-eslint/utils': 8.17.0(eslint@9.16.0)(typescript@5.6.3)
+ debug: 4.3.7
+ eslint: 9.16.0
+ ts-api-utils: 1.4.3(typescript@5.6.3)
+ optionalDependencies:
+ typescript: 5.6.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/types@8.17.0': {}
+
+ '@typescript-eslint/typescript-estree@8.17.0(typescript@5.6.3)':
+ dependencies:
+ '@typescript-eslint/types': 8.17.0
+ '@typescript-eslint/visitor-keys': 8.17.0
+ debug: 4.3.7
+ fast-glob: 3.3.2
+ is-glob: 4.0.3
minimatch: 9.0.5
semver: 7.6.3
ts-api-utils: 1.4.3(typescript@5.6.3)
@@ -1683,17 +3742,80 @@ snapshots:
'@typescript-eslint/types': 8.17.0
eslint-visitor-keys: 4.2.0
- '@vitejs/plugin-react@4.3.4(vite@6.0.3)':
+ '@vitejs/plugin-react@4.3.4(vite@6.0.3(@types/node@22.10.2))':
dependencies:
'@babel/core': 7.26.0
'@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.0)
'@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.0)
'@types/babel__core': 7.20.5
react-refresh: 0.14.2
- vite: 6.0.3
+ vite: 6.0.3(@types/node@22.10.2)
transitivePeerDependencies:
- supports-color
+ '@vitest/expect@2.0.5':
+ dependencies:
+ '@vitest/spy': 2.0.5
+ '@vitest/utils': 2.0.5
+ chai: 5.1.2
+ tinyrainbow: 1.2.0
+
+ '@vitest/expect@2.1.8':
+ dependencies:
+ '@vitest/spy': 2.1.8
+ '@vitest/utils': 2.1.8
+ chai: 5.1.2
+ tinyrainbow: 1.2.0
+
+ '@vitest/mocker@2.1.8(msw@2.6.8(@types/node@22.10.2)(typescript@5.6.3))(vite@5.4.11(@types/node@22.10.2))':
+ dependencies:
+ '@vitest/spy': 2.1.8
+ estree-walker: 3.0.3
+ magic-string: 0.30.14
+ optionalDependencies:
+ msw: 2.6.8(@types/node@22.10.2)(typescript@5.6.3)
+ vite: 5.4.11(@types/node@22.10.2)
+
+ '@vitest/pretty-format@2.0.5':
+ dependencies:
+ tinyrainbow: 1.2.0
+
+ '@vitest/pretty-format@2.1.8':
+ dependencies:
+ tinyrainbow: 1.2.0
+
+ '@vitest/runner@2.1.8':
+ dependencies:
+ '@vitest/utils': 2.1.8
+ pathe: 1.1.2
+
+ '@vitest/snapshot@2.1.8':
+ dependencies:
+ '@vitest/pretty-format': 2.1.8
+ magic-string: 0.30.14
+ pathe: 1.1.2
+
+ '@vitest/spy@2.0.5':
+ dependencies:
+ tinyspy: 3.0.2
+
+ '@vitest/spy@2.1.8':
+ dependencies:
+ tinyspy: 3.0.2
+
+ '@vitest/utils@2.0.5':
+ dependencies:
+ '@vitest/pretty-format': 2.0.5
+ estree-walker: 3.0.3
+ loupe: 3.1.2
+ tinyrainbow: 1.2.0
+
+ '@vitest/utils@2.1.8':
+ dependencies:
+ '@vitest/pretty-format': 2.1.8
+ loupe: 3.1.2
+ tinyrainbow: 1.2.0
+
acorn-jsx@5.3.2(acorn@8.14.0):
dependencies:
acorn: 8.14.0
@@ -1707,14 +3829,54 @@ snapshots:
json-schema-traverse: 0.4.1
uri-js: 4.4.1
+ ansi-escapes@4.3.2:
+ dependencies:
+ type-fest: 0.21.3
+
+ ansi-regex@5.0.1: {}
+
+ ansi-regex@6.1.0: {}
+
ansi-styles@4.3.0:
dependencies:
color-convert: 2.0.1
+ ansi-styles@5.2.0: {}
+
argparse@2.0.1: {}
+ aria-query@5.3.0:
+ dependencies:
+ dequal: 2.0.3
+
+ aria-query@5.3.2: {}
+
+ assertion-error@2.0.1: {}
+
+ ast-types@0.16.1:
+ dependencies:
+ tslib: 2.6.2
+
+ asynckit@0.4.0: {}
+
+ available-typed-arrays@1.0.7:
+ dependencies:
+ possible-typed-array-names: 1.0.0
+
+ axios@1.7.9:
+ dependencies:
+ follow-redirects: 1.15.9
+ form-data: 4.0.1
+ proxy-from-env: 1.1.0
+ transitivePeerDependencies:
+ - debug
+
balanced-match@1.0.2: {}
+ better-opn@3.0.2:
+ dependencies:
+ open: 8.4.2
+
brace-expansion@1.1.11:
dependencies:
balanced-match: 1.0.2
@@ -1728,6 +3890,8 @@ snapshots:
dependencies:
fill-range: 7.1.1
+ browser-assert@1.2.1: {}
+
browserslist@4.24.2:
dependencies:
caniuse-lite: 1.0.30001686
@@ -1735,29 +3899,97 @@ snapshots:
node-releases: 2.0.18
update-browserslist-db: 1.1.1(browserslist@4.24.2)
+ cac@6.7.14: {}
+
+ call-bind-apply-helpers@1.0.0:
+ dependencies:
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+
+ call-bind-apply-helpers@1.0.1:
+ dependencies:
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+
+ call-bind@1.0.8:
+ dependencies:
+ call-bind-apply-helpers: 1.0.0
+ es-define-property: 1.0.1
+ get-intrinsic: 1.2.5
+ set-function-length: 1.2.2
+
+ call-bound@1.0.3:
+ dependencies:
+ call-bind-apply-helpers: 1.0.1
+ get-intrinsic: 1.2.6
+
callsites@3.1.0: {}
+ camelcase@6.3.0: {}
+
camelize@1.0.1: {}
caniuse-lite@1.0.30001686: {}
+ chai@5.1.2:
+ dependencies:
+ assertion-error: 2.0.1
+ check-error: 2.1.1
+ deep-eql: 5.0.2
+ loupe: 3.1.2
+ pathval: 2.0.0
+
+ chalk@3.0.0:
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+
chalk@4.1.2:
dependencies:
ansi-styles: 4.3.0
supports-color: 7.2.0
+ check-error@2.1.1: {}
+
+ chromatic@11.20.0: {}
+
+ cli-width@4.1.0: {}
+
+ cliui@8.0.1:
+ dependencies:
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+ wrap-ansi: 7.0.0
+
+ clone@2.1.2: {}
+
color-convert@2.0.1:
dependencies:
color-name: 1.1.4
color-name@1.1.4: {}
+ combined-stream@1.0.8:
+ dependencies:
+ delayed-stream: 1.0.0
+
concat-map@0.0.1: {}
convert-source-map@2.0.0: {}
+ cookie@0.7.2: {}
+
cookie@1.0.2: {}
+ cosmiconfig@8.3.6(typescript@5.6.3):
+ dependencies:
+ import-fresh: 3.3.0
+ js-yaml: 4.1.0
+ parse-json: 5.2.0
+ path-type: 4.0.0
+ optionalDependencies:
+ typescript: 5.6.3
+
cross-spawn@7.0.6:
dependencies:
path-key: 3.1.1
@@ -1772,16 +4004,121 @@ snapshots:
css-color-keywords: 1.0.0
postcss-value-parser: 4.2.0
+ css.escape@1.5.1: {}
+
csstype@3.1.3: {}
debug@4.3.7:
dependencies:
ms: 2.1.3
+ deep-eql@5.0.2: {}
+
+ deep-equal@1.1.2:
+ dependencies:
+ is-arguments: 1.1.1
+ is-date-object: 1.1.0
+ is-regex: 1.2.1
+ object-is: 1.1.6
+ object-keys: 1.1.1
+ regexp.prototype.flags: 1.5.3
+
deep-is@0.1.4: {}
+ define-data-property@1.1.4:
+ dependencies:
+ es-define-property: 1.0.1
+ es-errors: 1.3.0
+ gopd: 1.2.0
+
+ define-lazy-prop@2.0.0: {}
+
+ define-properties@1.2.1:
+ dependencies:
+ define-data-property: 1.1.4
+ has-property-descriptors: 1.0.2
+ object-keys: 1.1.1
+
+ delayed-stream@1.0.0: {}
+
+ dequal@2.0.3: {}
+
+ doctrine@3.0.0:
+ dependencies:
+ esutils: 2.0.3
+
+ dom-accessibility-api@0.5.16: {}
+
+ dom-accessibility-api@0.6.3: {}
+
+ dompurify@3.2.3:
+ optionalDependencies:
+ '@types/trusted-types': 2.0.7
+
+ dot-case@3.0.4:
+ dependencies:
+ no-case: 3.0.4
+ tslib: 2.6.2
+
+ dunder-proto@1.0.0:
+ dependencies:
+ call-bind-apply-helpers: 1.0.0
+ es-errors: 1.3.0
+ gopd: 1.2.0
+
electron-to-chromium@1.5.71: {}
+ emoji-regex@8.0.0: {}
+
+ entities@4.5.0: {}
+
+ error-ex@1.3.2:
+ dependencies:
+ is-arrayish: 0.2.1
+
+ es-define-property@1.0.1: {}
+
+ es-errors@1.3.0: {}
+
+ es-module-lexer@1.5.4: {}
+
+ es-object-atoms@1.0.0:
+ dependencies:
+ es-errors: 1.3.0
+
+ esbuild-register@3.6.0(esbuild@0.24.0):
+ dependencies:
+ debug: 4.3.7
+ esbuild: 0.24.0
+ transitivePeerDependencies:
+ - supports-color
+
+ esbuild@0.21.5:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.21.5
+ '@esbuild/android-arm': 0.21.5
+ '@esbuild/android-arm64': 0.21.5
+ '@esbuild/android-x64': 0.21.5
+ '@esbuild/darwin-arm64': 0.21.5
+ '@esbuild/darwin-x64': 0.21.5
+ '@esbuild/freebsd-arm64': 0.21.5
+ '@esbuild/freebsd-x64': 0.21.5
+ '@esbuild/linux-arm': 0.21.5
+ '@esbuild/linux-arm64': 0.21.5
+ '@esbuild/linux-ia32': 0.21.5
+ '@esbuild/linux-loong64': 0.21.5
+ '@esbuild/linux-mips64el': 0.21.5
+ '@esbuild/linux-ppc64': 0.21.5
+ '@esbuild/linux-riscv64': 0.21.5
+ '@esbuild/linux-s390x': 0.21.5
+ '@esbuild/linux-x64': 0.21.5
+ '@esbuild/netbsd-x64': 0.21.5
+ '@esbuild/openbsd-x64': 0.21.5
+ '@esbuild/sunos-x64': 0.21.5
+ '@esbuild/win32-arm64': 0.21.5
+ '@esbuild/win32-ia32': 0.21.5
+ '@esbuild/win32-x64': 0.21.5
+
esbuild@0.24.0:
optionalDependencies:
'@esbuild/aix-ppc64': 0.24.0
@@ -1821,6 +4158,16 @@ snapshots:
dependencies:
eslint: 9.16.0
+ eslint-plugin-storybook@0.11.1(eslint@9.16.0)(typescript@5.6.3):
+ dependencies:
+ '@storybook/csf': 0.1.12
+ '@typescript-eslint/utils': 8.17.0(eslint@9.16.0)(typescript@5.6.3)
+ eslint: 9.16.0
+ ts-dedent: 2.2.0
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+
eslint-scope@8.2.0:
dependencies:
esrecurse: 4.3.0
@@ -1875,6 +4222,8 @@ snapshots:
acorn-jsx: 5.3.2(acorn@8.14.0)
eslint-visitor-keys: 4.2.0
+ esprima@4.0.1: {}
+
esquery@1.6.0:
dependencies:
estraverse: 5.3.0
@@ -1885,10 +4234,28 @@ snapshots:
estraverse@5.3.0: {}
+ estree-walker@2.0.2: {}
+
+ estree-walker@3.0.3:
+ dependencies:
+ '@types/estree': 1.0.6
+
esutils@2.0.3: {}
+ eventemitter3@2.0.3: {}
+
+ eventemitter3@5.0.1: {}
+
+ expect-type@1.1.0: {}
+
+ extend@3.0.2: {}
+
fast-deep-equal@3.1.3: {}
+ fast-diff@1.1.2: {}
+
+ fast-diff@1.3.0: {}
+
fast-glob@3.3.2:
dependencies:
'@nodelib/fs.stat': 2.0.5
@@ -1909,6 +4276,8 @@ snapshots:
dependencies:
flat-cache: 4.0.1
+ filesize@10.1.6: {}
+
fill-range@7.1.1:
dependencies:
to-regex-range: 5.0.1
@@ -1925,11 +4294,53 @@ snapshots:
flatted@3.3.2: {}
+ follow-redirects@1.15.9: {}
+
+ for-each@0.3.3:
+ dependencies:
+ is-callable: 1.2.7
+
+ form-data@4.0.1:
+ dependencies:
+ asynckit: 0.4.0
+ combined-stream: 1.0.8
+ mime-types: 2.1.35
+
fsevents@2.3.3:
optional: true
+ function-bind@1.1.2: {}
+
+ functions-have-names@1.2.3: {}
+
gensync@1.0.0-beta.2: {}
+ get-caller-file@2.0.5: {}
+
+ get-intrinsic@1.2.5:
+ dependencies:
+ call-bind-apply-helpers: 1.0.0
+ dunder-proto: 1.0.0
+ es-define-property: 1.0.1
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+ gopd: 1.2.0
+ has-symbols: 1.1.0
+ hasown: 2.0.2
+
+ get-intrinsic@1.2.6:
+ dependencies:
+ call-bind-apply-helpers: 1.0.1
+ dunder-proto: 1.0.0
+ es-define-property: 1.0.1
+ es-errors: 1.3.0
+ es-object-atoms: 1.0.0
+ function-bind: 1.1.2
+ gopd: 1.2.0
+ has-symbols: 1.1.0
+ hasown: 2.0.2
+ math-intrinsics: 1.1.0
+
glob-parent@5.1.2:
dependencies:
is-glob: 4.0.3
@@ -1944,10 +4355,39 @@ snapshots:
globals@15.13.0: {}
+ gopd@1.2.0: {}
+
+ graceful-fs@4.2.11:
+ optional: true
+
graphemer@1.4.0: {}
+ graphql@16.9.0: {}
+
has-flag@4.0.0: {}
+ has-property-descriptors@1.0.2:
+ dependencies:
+ es-define-property: 1.0.1
+
+ has-symbols@1.1.0: {}
+
+ has-tostringtag@1.0.2:
+ dependencies:
+ has-symbols: 1.1.0
+
+ hasown@2.0.2:
+ dependencies:
+ function-bind: 1.1.2
+
+ headers-polyfill@4.0.3: {}
+
+ hoist-non-react-statics@3.3.2:
+ dependencies:
+ react-is: 16.13.1
+
+ husky@9.1.7: {}
+
ignore@5.3.2: {}
immer@10.1.1: {}
@@ -1959,14 +4399,61 @@ snapshots:
imurmurhash@0.1.4: {}
+ indent-string@4.0.0: {}
+
+ inherits@2.0.4: {}
+
+ is-arguments@1.1.1:
+ dependencies:
+ call-bind: 1.0.8
+ has-tostringtag: 1.0.2
+
+ is-arrayish@0.2.1: {}
+
+ is-callable@1.2.7: {}
+
+ is-core-module@2.15.1:
+ dependencies:
+ hasown: 2.0.2
+
+ is-date-object@1.1.0:
+ dependencies:
+ call-bound: 1.0.3
+ has-tostringtag: 1.0.2
+
+ is-docker@2.2.1: {}
+
is-extglob@2.1.1: {}
+ is-fullwidth-code-point@3.0.0: {}
+
+ is-generator-function@1.0.10:
+ dependencies:
+ has-tostringtag: 1.0.2
+
is-glob@4.0.3:
dependencies:
is-extglob: 2.1.1
+ is-node-process@1.2.0: {}
+
is-number@7.0.0: {}
+ is-regex@1.2.1:
+ dependencies:
+ call-bound: 1.0.3
+ gopd: 1.2.0
+ has-tostringtag: 1.0.2
+ hasown: 2.0.2
+
+ is-typed-array@1.1.13:
+ dependencies:
+ which-typed-array: 1.1.16
+
+ is-wsl@2.2.0:
+ dependencies:
+ is-docker: 2.2.1
+
isexe@2.0.0: {}
js-tokens@4.0.0: {}
@@ -1975,16 +4462,28 @@ snapshots:
dependencies:
argparse: 2.0.1
+ jsdoc-type-pratt-parser@4.1.0: {}
+
jsesc@3.0.2: {}
json-buffer@3.0.1: {}
+ json-parse-even-better-errors@2.3.1: {}
+
json-schema-traverse@0.4.1: {}
json-stable-stringify-without-jsonify@1.0.1: {}
json5@2.2.3: {}
+ jsonfile@6.1.0:
+ dependencies:
+ universalify: 2.0.1
+ optionalDependencies:
+ graceful-fs: 4.2.11
+
+ jwt-decode@4.0.0: {}
+
keyv@4.5.4:
dependencies:
json-buffer: 3.0.1
@@ -1994,20 +4493,54 @@ snapshots:
prelude-ls: 1.2.1
type-check: 0.4.0
+ lines-and-columns@1.2.4: {}
+
locate-path@6.0.0:
dependencies:
p-locate: 5.0.0
+ lodash-es@4.17.21: {}
+
+ lodash.clonedeep@4.5.0: {}
+
+ lodash.isequal@4.5.0: {}
+
lodash.merge@4.6.2: {}
+ lodash@4.17.21: {}
+
loose-envify@1.4.0:
dependencies:
js-tokens: 4.0.0
+ loupe@3.1.2: {}
+
+ lower-case@2.0.2:
+ dependencies:
+ tslib: 2.6.2
+
lru-cache@5.1.1:
dependencies:
yallist: 3.1.1
+ lz-string@1.5.0: {}
+
+ magic-string@0.27.0:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.0
+
+ magic-string@0.30.14:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.0
+
+ map-or-similar@1.5.0: {}
+
+ math-intrinsics@1.1.0: {}
+
+ memoizerific@1.11.3:
+ dependencies:
+ map-or-similar: 1.5.0
+
merge2@1.4.1: {}
micromatch@4.0.8:
@@ -2015,6 +4548,14 @@ snapshots:
braces: 3.0.3
picomatch: 2.3.1
+ mime-db@1.52.0: {}
+
+ mime-types@2.1.35:
+ dependencies:
+ mime-db: 1.52.0
+
+ min-indent@1.0.1: {}
+
minimatch@3.1.2:
dependencies:
brace-expansion: 1.1.11
@@ -2023,14 +4564,61 @@ snapshots:
dependencies:
brace-expansion: 2.0.1
+ minimist@1.2.8: {}
+
ms@2.1.3: {}
+ msw@2.6.8(@types/node@22.10.2)(typescript@5.6.3):
+ dependencies:
+ '@bundled-es-modules/cookie': 2.0.1
+ '@bundled-es-modules/statuses': 1.0.1
+ '@bundled-es-modules/tough-cookie': 0.1.6
+ '@inquirer/confirm': 5.1.0(@types/node@22.10.2)
+ '@mswjs/interceptors': 0.37.3
+ '@open-draft/deferred-promise': 2.2.0
+ '@open-draft/until': 2.1.0
+ '@types/cookie': 0.6.0
+ '@types/statuses': 2.0.5
+ chalk: 4.1.2
+ graphql: 16.9.0
+ headers-polyfill: 4.0.3
+ is-node-process: 1.2.0
+ outvariant: 1.4.3
+ path-to-regexp: 6.3.0
+ strict-event-emitter: 0.5.1
+ type-fest: 4.30.0
+ yargs: 17.7.2
+ optionalDependencies:
+ typescript: 5.6.3
+ transitivePeerDependencies:
+ - '@types/node'
+
+ mute-stream@2.0.0: {}
+
nanoid@3.3.8: {}
natural-compare@1.4.0: {}
+ no-case@3.0.4:
+ dependencies:
+ lower-case: 2.0.2
+ tslib: 2.6.2
+
node-releases@2.0.18: {}
+ object-is@1.1.6:
+ dependencies:
+ call-bind: 1.0.8
+ define-properties: 1.2.1
+
+ object-keys@1.1.1: {}
+
+ open@8.4.2:
+ dependencies:
+ define-lazy-prop: 2.0.0
+ is-docker: 2.2.1
+ is-wsl: 2.2.0
+
optionator@0.9.4:
dependencies:
deep-is: 0.1.4
@@ -2040,6 +4628,8 @@ snapshots:
type-check: 0.4.0
word-wrap: 1.2.5
+ outvariant@1.4.3: {}
+
p-limit@3.1.0:
dependencies:
yocto-queue: 0.1.0
@@ -2048,18 +4638,47 @@ snapshots:
dependencies:
p-limit: 3.1.0
+ parchment@1.1.4: {}
+
+ parchment@3.0.0: {}
+
parent-module@1.0.1:
dependencies:
callsites: 3.1.0
+ parse-json@5.2.0:
+ dependencies:
+ '@babel/code-frame': 7.26.2
+ error-ex: 1.3.2
+ json-parse-even-better-errors: 2.3.1
+ lines-and-columns: 1.2.4
+
path-exists@4.0.0: {}
path-key@3.1.1: {}
+ path-parse@1.0.7: {}
+
+ path-to-regexp@6.3.0: {}
+
+ path-type@4.0.0: {}
+
+ pathe@1.1.2: {}
+
+ pathval@2.0.0: {}
+
picocolors@1.1.1: {}
picomatch@2.3.1: {}
+ picomatch@4.0.2: {}
+
+ polished@4.3.1:
+ dependencies:
+ '@babel/runtime': 7.26.0
+
+ possible-typed-array-names@1.0.0: {}
+
postcss-value-parser@4.2.0: {}
postcss@8.4.38:
@@ -2076,16 +4695,100 @@ snapshots:
prelude-ls@1.2.1: {}
+ pretty-format@27.5.1:
+ dependencies:
+ ansi-regex: 5.0.1
+ ansi-styles: 5.2.0
+ react-is: 17.0.2
+
+ process@0.11.10: {}
+
+ proxy-from-env@1.1.0: {}
+
+ psl@1.15.0:
+ dependencies:
+ punycode: 2.3.1
+
punycode@2.3.1: {}
+ querystringify@2.2.0: {}
+
queue-microtask@1.2.3: {}
+ quill-delta@3.6.3:
+ dependencies:
+ deep-equal: 1.1.2
+ extend: 3.0.2
+ fast-diff: 1.1.2
+
+ quill-delta@5.1.0:
+ dependencies:
+ fast-diff: 1.3.0
+ lodash.clonedeep: 4.5.0
+ lodash.isequal: 4.5.0
+
+ quill@1.3.7:
+ dependencies:
+ clone: 2.1.2
+ deep-equal: 1.1.2
+ eventemitter3: 2.0.3
+ extend: 3.0.2
+ parchment: 1.1.4
+ quill-delta: 3.6.3
+
+ quill@2.0.3:
+ dependencies:
+ eventemitter3: 5.0.1
+ lodash-es: 4.17.21
+ parchment: 3.0.0
+ quill-delta: 5.1.0
+
+ react-confetti@6.1.0(react@18.3.1):
+ dependencies:
+ react: 18.3.1
+ tween-functions: 1.2.0
+
+ react-docgen-typescript@2.2.2(typescript@5.6.3):
+ dependencies:
+ typescript: 5.6.3
+
+ react-docgen@7.1.0:
+ dependencies:
+ '@babel/core': 7.26.0
+ '@babel/traverse': 7.26.4
+ '@babel/types': 7.26.3
+ '@types/babel__core': 7.20.5
+ '@types/babel__traverse': 7.20.6
+ '@types/doctrine': 0.0.9
+ '@types/resolve': 1.20.6
+ doctrine: 3.0.0
+ resolve: 1.22.8
+ strip-indent: 4.0.0
+ transitivePeerDependencies:
+ - supports-color
+
react-dom@18.3.1(react@18.3.1):
dependencies:
loose-envify: 1.4.0
react: 18.3.1
scheduler: 0.23.2
+ react-hook-form@7.54.1(react@18.3.1):
+ dependencies:
+ react: 18.3.1
+
+ react-is@16.13.1: {}
+
+ react-is@17.0.2: {}
+
+ react-quill@2.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
+ dependencies:
+ '@types/quill': 1.3.10
+ lodash: 4.17.21
+ quill: 1.3.7
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+
react-redux@9.1.2(@types/react@18.3.14)(react@18.3.1)(redux@5.0.1):
dependencies:
'@types/use-sync-external-store': 0.0.3
@@ -2111,16 +4814,58 @@ snapshots:
dependencies:
loose-envify: 1.4.0
+ recast@0.23.9:
+ dependencies:
+ ast-types: 0.16.1
+ esprima: 4.0.1
+ source-map: 0.6.1
+ tiny-invariant: 1.3.3
+ tslib: 2.6.2
+
+ redent@3.0.0:
+ dependencies:
+ indent-string: 4.0.0
+ strip-indent: 3.0.0
+
+ redux-persist@6.0.0(react@18.3.1)(redux@5.0.1):
+ dependencies:
+ redux: 5.0.1
+ optionalDependencies:
+ react: 18.3.1
+
redux-thunk@3.1.0(redux@5.0.1):
dependencies:
redux: 5.0.1
+ redux@4.2.1:
+ dependencies:
+ '@babel/runtime': 7.26.0
+
redux@5.0.1: {}
+ regenerator-runtime@0.14.1: {}
+
+ regexp.prototype.flags@1.5.3:
+ dependencies:
+ call-bind: 1.0.8
+ define-properties: 1.2.1
+ es-errors: 1.3.0
+ set-function-name: 2.0.2
+
+ require-directory@2.1.1: {}
+
+ requires-port@1.0.0: {}
+
reselect@5.1.1: {}
resolve-from@4.0.0: {}
+ resolve@1.22.8:
+ dependencies:
+ is-core-module: 2.15.1
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+
reusify@1.0.4: {}
rollup@4.28.0:
@@ -2161,6 +4906,22 @@ snapshots:
set-cookie-parser@2.7.1: {}
+ set-function-length@1.2.2:
+ dependencies:
+ define-data-property: 1.1.4
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+ get-intrinsic: 1.2.5
+ gopd: 1.2.0
+ has-property-descriptors: 1.0.2
+
+ set-function-name@2.0.2:
+ dependencies:
+ define-data-property: 1.1.4
+ es-errors: 1.3.0
+ functions-have-names: 1.2.3
+ has-property-descriptors: 1.0.2
+
shallowequal@1.1.0: {}
shebang-command@2.0.0:
@@ -2169,8 +4930,59 @@ snapshots:
shebang-regex@3.0.0: {}
+ siginfo@2.0.0: {}
+
+ signal-exit@4.1.0: {}
+
+ snake-case@3.0.4:
+ dependencies:
+ dot-case: 3.0.4
+ tslib: 2.6.2
+
source-map-js@1.2.1: {}
+ source-map@0.6.1: {}
+
+ stackback@0.0.2: {}
+
+ statuses@2.0.1: {}
+
+ std-env@3.8.0: {}
+
+ storybook@8.4.7:
+ dependencies:
+ '@storybook/core': 8.4.7
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ strict-event-emitter@0.5.1: {}
+
+ string-width@4.2.3:
+ dependencies:
+ emoji-regex: 8.0.0
+ is-fullwidth-code-point: 3.0.0
+ strip-ansi: 6.0.1
+
+ strip-ansi@6.0.1:
+ dependencies:
+ ansi-regex: 5.0.1
+
+ strip-ansi@7.1.0:
+ dependencies:
+ ansi-regex: 6.1.0
+
+ strip-bom@3.0.0: {}
+
+ strip-indent@3.0.0:
+ dependencies:
+ min-indent: 1.0.1
+
+ strip-indent@4.0.0:
+ dependencies:
+ min-indent: 1.0.1
+
strip-json-comments@3.1.1: {}
styled-components@6.1.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
@@ -2193,22 +5005,61 @@ snapshots:
dependencies:
has-flag: 4.0.0
+ supports-preserve-symlinks-flag@1.0.0: {}
+
+ svg-parser@2.0.4: {}
+
+ tiny-invariant@1.3.3: {}
+
+ tinybench@2.9.0: {}
+
+ tinyexec@0.3.1: {}
+
+ tinypool@1.0.2: {}
+
+ tinyrainbow@1.2.0: {}
+
+ tinyspy@3.0.2: {}
+
to-regex-range@5.0.1:
dependencies:
is-number: 7.0.0
+ tough-cookie@4.1.4:
+ dependencies:
+ psl: 1.15.0
+ punycode: 2.3.1
+ universalify: 0.2.0
+ url-parse: 1.5.10
+
ts-api-utils@1.4.3(typescript@5.6.3):
dependencies:
typescript: 5.6.3
+ ts-dedent@2.2.0: {}
+
+ tsconfig-paths@4.2.0:
+ dependencies:
+ json5: 2.2.3
+ minimist: 1.2.8
+ strip-bom: 3.0.0
+
tslib@2.6.2: {}
turbo-stream@2.4.0: {}
+ tween-functions@1.2.0: {}
+
type-check@0.4.0:
dependencies:
prelude-ls: 1.2.1
+ type-fest@0.21.3: {}
+
+ type-fest@2.19.0: {}
+
+ type-fest@4.30.0: {}
+
typescript-eslint@8.17.0(eslint@9.16.0)(typescript@5.6.3):
dependencies:
'@typescript-eslint/eslint-plugin': 8.17.0(@typescript-eslint/parser@8.17.0(eslint@9.16.0)(typescript@5.6.3))(eslint@9.16.0)(typescript@5.6.3)
@@ -2222,6 +5073,17 @@ snapshots:
typescript@5.6.3: {}
+ undici-types@6.20.0: {}
+
+ universalify@0.2.0: {}
+
+ universalify@2.0.1: {}
+
+ unplugin@1.16.0:
+ dependencies:
+ acorn: 8.14.0
+ webpack-virtual-modules: 0.6.2
+
update-browserslist-db@1.1.1(browserslist@4.24.2):
dependencies:
browserslist: 4.24.2
@@ -2232,24 +5094,158 @@ snapshots:
dependencies:
punycode: 2.3.1
+ url-parse@1.5.10:
+ dependencies:
+ querystringify: 2.2.0
+ requires-port: 1.0.0
+
use-sync-external-store@1.4.0(react@18.3.1):
dependencies:
react: 18.3.1
- vite@6.0.3:
+ util@0.12.5:
+ dependencies:
+ inherits: 2.0.4
+ is-arguments: 1.1.1
+ is-generator-function: 1.0.10
+ is-typed-array: 1.1.13
+ which-typed-array: 1.1.16
+
+ uuid@9.0.1: {}
+
+ vite-node@2.1.8(@types/node@22.10.2):
+ dependencies:
+ cac: 6.7.14
+ debug: 4.3.7
+ es-module-lexer: 1.5.4
+ pathe: 1.1.2
+ vite: 5.4.11(@types/node@22.10.2)
+ transitivePeerDependencies:
+ - '@types/node'
+ - less
+ - lightningcss
+ - sass
+ - sass-embedded
+ - stylus
+ - sugarss
+ - supports-color
+ - terser
+
+ vite-plugin-svgr@4.3.0(rollup@4.28.0)(typescript@5.6.3)(vite@6.0.3(@types/node@22.10.2)):
+ dependencies:
+ '@rollup/pluginutils': 5.1.3(rollup@4.28.0)
+ '@svgr/core': 8.1.0(typescript@5.6.3)
+ '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.6.3))
+ vite: 6.0.3(@types/node@22.10.2)
+ transitivePeerDependencies:
+ - rollup
+ - supports-color
+ - typescript
+
+ vite@5.4.11(@types/node@22.10.2):
+ dependencies:
+ esbuild: 0.21.5
+ postcss: 8.4.49
+ rollup: 4.28.0
+ optionalDependencies:
+ '@types/node': 22.10.2
+ fsevents: 2.3.3
+
+ vite@6.0.3(@types/node@22.10.2):
dependencies:
esbuild: 0.24.0
postcss: 8.4.49
rollup: 4.28.0
optionalDependencies:
+ '@types/node': 22.10.2
fsevents: 2.3.3
+ vitest@2.1.8(@types/node@22.10.2)(msw@2.6.8(@types/node@22.10.2)(typescript@5.6.3)):
+ dependencies:
+ '@vitest/expect': 2.1.8
+ '@vitest/mocker': 2.1.8(msw@2.6.8(@types/node@22.10.2)(typescript@5.6.3))(vite@5.4.11(@types/node@22.10.2))
+ '@vitest/pretty-format': 2.1.8
+ '@vitest/runner': 2.1.8
+ '@vitest/snapshot': 2.1.8
+ '@vitest/spy': 2.1.8
+ '@vitest/utils': 2.1.8
+ chai: 5.1.2
+ debug: 4.3.7
+ expect-type: 1.1.0
+ magic-string: 0.30.14
+ pathe: 1.1.2
+ std-env: 3.8.0
+ tinybench: 2.9.0
+ tinyexec: 0.3.1
+ tinypool: 1.0.2
+ tinyrainbow: 1.2.0
+ vite: 5.4.11(@types/node@22.10.2)
+ vite-node: 2.1.8(@types/node@22.10.2)
+ why-is-node-running: 2.3.0
+ optionalDependencies:
+ '@types/node': 22.10.2
+ transitivePeerDependencies:
+ - less
+ - lightningcss
+ - msw
+ - sass
+ - sass-embedded
+ - stylus
+ - sugarss
+ - supports-color
+ - terser
+
+ webpack-virtual-modules@0.6.2: {}
+
+ which-typed-array@1.1.16:
+ dependencies:
+ available-typed-arrays: 1.0.7
+ call-bind: 1.0.8
+ for-each: 0.3.3
+ gopd: 1.2.0
+ has-tostringtag: 1.0.2
+
which@2.0.2:
dependencies:
isexe: 2.0.0
+ why-is-node-running@2.3.0:
+ dependencies:
+ siginfo: 2.0.0
+ stackback: 0.0.2
+
word-wrap@1.2.5: {}
+ wrap-ansi@6.2.0:
+ dependencies:
+ ansi-styles: 4.3.0
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+
+ wrap-ansi@7.0.0:
+ dependencies:
+ ansi-styles: 4.3.0
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+
+ ws@8.18.0: {}
+
+ y18n@5.0.8: {}
+
yallist@3.1.1: {}
+ yargs-parser@21.1.1: {}
+
+ yargs@17.7.2:
+ dependencies:
+ cliui: 8.0.1
+ escalade: 3.2.0
+ get-caller-file: 2.0.5
+ require-directory: 2.1.1
+ string-width: 4.2.3
+ y18n: 5.0.8
+ yargs-parser: 21.1.1
+
yocto-queue@0.1.0: {}
+
+ yoctocolors-cjs@2.1.2: {}
diff --git a/src/App.css b/src/App.css
deleted file mode 100644
index b9d355d..0000000
--- a/src/App.css
+++ /dev/null
@@ -1,42 +0,0 @@
-#root {
- max-width: 1280px;
- margin: 0 auto;
- padding: 2rem;
- text-align: center;
-}
-
-.logo {
- height: 6em;
- padding: 1.5em;
- will-change: filter;
- transition: filter 300ms;
-}
-.logo:hover {
- filter: drop-shadow(0 0 2em #646cffaa);
-}
-.logo.react:hover {
- filter: drop-shadow(0 0 2em #61dafbaa);
-}
-
-@keyframes logo-spin {
- from {
- transform: rotate(0deg);
- }
- to {
- transform: rotate(360deg);
- }
-}
-
-@media (prefers-reduced-motion: no-preference) {
- a:nth-of-type(2) .logo {
- animation: logo-spin infinite 20s linear;
- }
-}
-
-.card {
- padding: 2em;
-}
-
-.read-the-docs {
- color: #888;
-}
diff --git a/src/App.tsx b/src/App.tsx
index 3d7ded3..1a9921b 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,35 +1,33 @@
-import { useState } from 'react'
-import reactLogo from './assets/react.svg'
-import viteLogo from '/vite.svg'
-import './App.css'
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
+import { RouterProvider, createBrowserRouter } from 'react-router';
+import router from '@/routes/router';
+import { Provider } from 'react-redux'; // Redux Provider 임포트
+import GlobalStyle from './styles/GlobalStyle';
+import { PersistGate } from 'redux-persist/integration/react';
+import { persistor, store } from './store/store';
-function App() {
- const [count, setCount] = useState(0)
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ refetchOnWindowFocus: false, // window 가 다시 포커스 될 때
+ refetchOnMount: false, // 쿼리의 새 인스턴스가 마운트 될 때
+ refetchOnReconnect: false, // 네트워크가 끊어졌다가 다시 연결될 때
+ },
+ },
+});
+const App = () => {
+ const appRouter = createBrowserRouter(router);
return (
- <>
-
- Vite + React
-
-
setCount((count) => count + 1)}>
- count is {count}
-
-
- Edit src/App.tsx and save to test HMR
-
-
-
- Click on the Vite and React logos to learn more
-
- >
- )
-}
+
+
+
+
+
+
+
+
+ );
+};
-export default App
+export default App;
diff --git a/src/admin/AdminRoute.tsx b/src/admin/AdminRoute.tsx
new file mode 100644
index 0000000..47118d5
--- /dev/null
+++ b/src/admin/AdminRoute.tsx
@@ -0,0 +1,27 @@
+import { Navigate } from 'react-router';
+import { useSelector } from 'react-redux';
+import { RootState } from '@/store/rootReducer';
+
+interface ProtectedRouteProps {
+ allowedRoles: string[];
+ children: React.ReactNode;
+}
+
+const ProtectedRoute = ({ allowedRoles, children }: ProtectedRouteProps) => {
+ const { userInfo } = useSelector((state: RootState) => state.user);
+
+ // 로그인하지 않은 경우
+ if (!userInfo) {
+ return ;
+ } else if (!allowedRoles.includes(userInfo.role)) {
+ }
+
+ // 역할이 허용되지 않은 경우
+ if (!allowedRoles.includes(userInfo.role)) {
+ return ;
+ }
+
+ return <>{children}>; // 자식 요소 렌더링
+};
+
+export default ProtectedRoute;
diff --git a/src/admin/UserCard.tsx b/src/admin/UserCard.tsx
new file mode 100644
index 0000000..12c12f7
--- /dev/null
+++ b/src/admin/UserCard.tsx
@@ -0,0 +1,81 @@
+import styled from 'styled-components';
+import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/outline';
+
+interface UserCardProps {
+ nickname: string;
+ email: string;
+ createdAt: string;
+ icon: string | null;
+ isOpen: boolean;
+}
+
+// Styled Components
+const CardContainer = styled.div<{ isOpen: boolean }>`
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 16px;
+ background-color: white;
+ border: 1px solid #ddd;
+ border-radius: ${(props) => (props.isOpen ? '8px 8px 0 0' : '8px')};
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
+ cursor: pointer;
+ transition: all 0.3s ease;
+
+ &:hover {
+ background-color: #f7f7f7;
+ }
+`;
+
+const UserInfo = styled.div`
+ display: flex;
+ align-items: center;
+`;
+
+const Avatar = styled.img`
+ width: 50px;
+ height: 50px;
+ border-radius: 50%;
+ margin-right: 12px;
+`;
+
+const TextContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+`;
+
+const Name = styled.p`
+ font-weight: bold;
+`;
+
+const IconWrapper = styled.div`
+ width: 24px;
+ height: 24px;
+
+ svg {
+ width: 100%;
+ height: 100%;
+ }
+`;
+
+const UserCard = ({ nickname, icon, isOpen }: UserCardProps) => {
+ return (
+
+
+
+
+ {nickname}
+
+
+
+
+ {isOpen ? : }
+
+
+ );
+};
+
+export default UserCard;
diff --git a/src/admin/UserList.tsx b/src/admin/UserList.tsx
new file mode 100644
index 0000000..63db182
--- /dev/null
+++ b/src/admin/UserList.tsx
@@ -0,0 +1,118 @@
+import { useEffect, useState } from 'react';
+import { AdminData } from '@/types/admindata';
+import UserCard from './UserCard';
+import styled from 'styled-components';
+import { deleteUser, fetchAdminData } from '@/apis/admin.api';
+
+// Styled Components
+const UserListContainer = styled.div`
+ width: 600px;
+ margin: 0;
+ padding-left: 10px;
+ max-height: 500px;
+ overflow-y: auto;
+ border: 1px solid #ddd;
+ border-radius: 8px;
+`;
+
+const ListItem = styled.div`
+ margin-bottom: 12px; /* 리스트 아이템 간 간격 추가 */
+ margin-top: 12px;
+ margin-right: 12px;
+`;
+
+const DropdownContent = styled.div`
+ background-color: #f9f9f9;
+ padding: 16px;
+ border: 1px solid #ddd;
+ border-top: none;
+ border-radius: 0 0 8px 8px;
+ box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.1);
+`;
+
+const DeleteButton = styled.button`
+ background-color: #ff4d4f;
+ color: white;
+ padding: 8px 12px;
+ border: none;
+ border-radius: 4px;
+ cursor: pointer;
+ font-weight: bold;
+ margin-top: 10px;
+ transition: background-color 0.3s;
+
+ &:hover {
+ background-color: #e33e3e;
+ }
+`;
+
+const UserList = () => {
+ const [users, setUsers] = useState([]);
+ const [openUserId, setOpenUserId] = useState(null);
+
+ const toggleDropdown = (id: number) => {
+ setOpenUserId((prev) => (prev === id ? null : id));
+ };
+
+ const handleDeleteUser = async (id: number) => {
+ const confirmed = window.confirm(`유저 ID ${id}를 삭제하시겠습니까?`);
+ if (!confirmed) return;
+
+ try {
+ const result = await deleteUser(id);
+ if (result.success) {
+ alert('회원 탈퇴가 완료되었습니다.');
+ setUsers((prevUsers) => prevUsers.filter((user) => user.id !== id));
+ } else {
+ alert('회원 탈퇴에 실패했습니다.');
+ }
+ } catch (error: any) {
+ alert(`오류 발생: ${error.message}`);
+ }
+ };
+
+ useEffect(() => {
+ const loadUsers = async () => {
+ try {
+ const data = await fetchAdminData();
+ setUsers(data);
+ } catch (error) {
+ console.error('Failed to load users:', error);
+ }
+ };
+
+ loadUsers();
+ }, []);
+
+ return (
+
+ {users.map((user) => (
+
+ toggleDropdown(user.id)}>
+
+
+
+ {openUserId === user.id && (
+
+ 유저 ID: {user.id}
+ 닉네임: {user.nickname}
+ 이메일: {user.email}
+ 가입 일자: {user.created_at}
+ handleDeleteUser(user.id)}>
+ 회원탈퇴
+
+
+ )}
+
+ ))}
+
+ );
+};
+
+export default UserList;
diff --git a/src/apis/admin.api.ts b/src/apis/admin.api.ts
new file mode 100644
index 0000000..54127f9
--- /dev/null
+++ b/src/apis/admin.api.ts
@@ -0,0 +1,26 @@
+import { AdminData } from '@/types/admindata';
+import { httpClient } from './http.api';
+
+export const fetchAdminData = async () => {
+ try {
+ const response = await httpClient.get('/api/admin');
+ console.log('응답 데이터:', response.data);
+ return response.data;
+ } catch (error) {
+ console.error('Error fetching admin data:', error);
+ throw error;
+ }
+};
+
+export const deleteUser = async (id: number): Promise<{ success: boolean }> => {
+ try {
+ const response = await httpClient.delete(`/api/users/${id}/delete`);
+ console.log('응답 데이터:', response.data);
+ return response.data;
+ } catch (error: any) {
+ console.error('API 호출 실패:', error);
+ throw new Error(
+ error.response?.data?.message || '회원 탈퇴 중 오류가 발생했습니다.'
+ );
+ }
+};
diff --git a/src/apis/api-path.ts b/src/apis/api-path.ts
new file mode 100644
index 0000000..008f557
--- /dev/null
+++ b/src/apis/api-path.ts
@@ -0,0 +1 @@
+export const API_PATH = {};
diff --git a/src/apis/auth.api.ts b/src/apis/auth.api.ts
new file mode 100644
index 0000000..3edd653
--- /dev/null
+++ b/src/apis/auth.api.ts
@@ -0,0 +1,13 @@
+import { JoinProps } from '@/pages/JoinPage';
+import { httpClient } from './http.api';
+
+export const join = async (data: JoinProps) => {
+ const response = await httpClient.post('/api/users/join', data);
+ return response.data;
+};
+
+export interface LoginResponse {
+ message: any;
+ success: boolean;
+ token?: string;
+}
diff --git a/src/apis/board.api.ts b/src/apis/board.api.ts
new file mode 100644
index 0000000..c27bc00
--- /dev/null
+++ b/src/apis/board.api.ts
@@ -0,0 +1,26 @@
+import { httpClient } from './http.api';
+
+export const fetchUpdateReview = async (
+ title: string,
+ tags: string[],
+ content: string
+) => {
+ {
+ const response = await httpClient.post('/api/posts', {
+ title,
+ tags,
+ content,
+ });
+ return response.data;
+ }
+};
+
+export const updateUserIntroduce = async (id: number, intro: string) => {
+ {
+ const response = await httpClient.put(`/api/users/${id}/intro`, {
+ intro,
+ });
+ console.log('인트로 변경 response: ' + response);
+ return response.data;
+ }
+};
diff --git a/src/apis/http.api.ts b/src/apis/http.api.ts
new file mode 100644
index 0000000..e36cc7c
--- /dev/null
+++ b/src/apis/http.api.ts
@@ -0,0 +1,52 @@
+import axios, { AxiosRequestConfig } from 'axios';
+
+import { getToken, removeToken } from '@/utils/token';
+
+export const BASE_URL = import.meta.env.VITE_API_BASE_URL;
+const DEFAULT_TIMEOUT = 30000;
+
+export const createClient = (config?: AxiosRequestConfig) => {
+ const token = getToken();
+ const axiosInstance = axios.create({
+ baseURL: BASE_URL,
+ timeout: DEFAULT_TIMEOUT,
+ headers: {
+ 'Content-Type': 'application/json',
+ Authorization: token ? `Bearer ${token}` : '',
+ },
+ withCredentials: true,
+ ...config,
+ });
+
+ axiosInstance.interceptors.request.use(
+ (config) => {
+ const token = getToken();
+ if (token) {
+ config.headers.Authorization = `Bearer ${token}`;
+ }
+ return config;
+ },
+ (error) => {
+ return Promise.reject(error);
+ }
+ );
+
+ axiosInstance.interceptors.response.use(
+ (response) => {
+ return response;
+ },
+ (error) => {
+ // 로그인 만료 처리
+ if (error.response.status === 401) {
+ removeToken();
+ window.location.href = '/login';
+ return;
+ }
+ return Promise.reject(error);
+ }
+ );
+
+ return axiosInstance;
+};
+
+export const httpClient = createClient();
diff --git a/src/apis/maindata.api.ts b/src/apis/maindata.api.ts
new file mode 100644
index 0000000..63b8e83
--- /dev/null
+++ b/src/apis/maindata.api.ts
@@ -0,0 +1,11 @@
+import { httpClient } from './http.api';
+import { mainData } from '@/types/main.model';
+
+export const fetchMainData = async () => {
+ const response = await httpClient.get('/api/main');
+ try {
+ return response.data;
+ } catch {
+ throw Error;
+ }
+};
diff --git a/src/apis/user-info.api.ts b/src/apis/user-info.api.ts
new file mode 100644
index 0000000..42aa144
--- /dev/null
+++ b/src/apis/user-info.api.ts
@@ -0,0 +1,52 @@
+import { httpClient } from './http.api';
+
+export interface Profile {
+ id: number;
+ email: string;
+ nickname: string;
+ introduce: string;
+ icon: string | null;
+}
+
+export interface Post {
+ id: number;
+ title: string;
+ content: string;
+ created_at: string;
+ updated_at: string | null;
+ view: number;
+ solved: number;
+ nickname: string;
+ comment_count: number;
+ like_count: number;
+ tags: string;
+}
+
+export interface UserData {
+ profile: Profile;
+ posts: Post[];
+}
+
+export const fetchUserInfo = async (nickname: string) => {
+ try {
+ const url = `/api/users/${nickname}`;
+ const response = await httpClient.get(url);
+ console.log(response);
+ return response.data;
+ } catch (error) {
+ console.error('Error fetching admin data:', error);
+ throw error;
+ }
+};
+
+export const fetchUserLikes = async (nickname: string) => {
+ try {
+ const url = `/api/users/${nickname}/likes`;
+ const response = await httpClient.get<{ posts: Post[] }>(url);
+ console.log(response.data.posts);
+ return response.data.posts;
+ } catch (error) {
+ console.error('Error fetching user likes:', error);
+ throw error;
+ }
+};
diff --git a/src/assets/DefaultAvatar.svg b/src/assets/DefaultAvatar.svg
new file mode 100644
index 0000000..e5daaa3
--- /dev/null
+++ b/src/assets/DefaultAvatar.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/assets/logo.svg b/src/assets/logo.svg
new file mode 100644
index 0000000..3ae79fb
--- /dev/null
+++ b/src/assets/logo.svg
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/qublogo.svg b/src/assets/qublogo.svg
new file mode 100644
index 0000000..3ae79fb
--- /dev/null
+++ b/src/assets/qublogo.svg
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/Header.tsx b/src/components/Header.tsx
new file mode 100644
index 0000000..5264699
--- /dev/null
+++ b/src/components/Header.tsx
@@ -0,0 +1,43 @@
+import styled from 'styled-components';
+import logo from '@/assets/logo.svg';
+import MenuButton from './MenuButton';
+import { useNavigate } from 'react-router';
+
+const Header = () => {
+ const navigate = useNavigate();
+
+ const handleLogoClick = () => {
+ navigate('/');
+ };
+
+ return (
+
+
+
+
+
+
+ );
+};
+
+export default Header;
+
+const HeaderContainer = styled.div`
+ width: 100%;
+ height: 170px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+`;
+
+const HeaderWrapper = styled.div`
+ width: 980px;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+`;
+
+const Logo = styled.img`
+ cursor: pointer;
+`;
diff --git a/src/components/MenuButton.tsx b/src/components/MenuButton.tsx
new file mode 100644
index 0000000..807a178
--- /dev/null
+++ b/src/components/MenuButton.tsx
@@ -0,0 +1,163 @@
+import { useState } from 'react';
+import styled from 'styled-components';
+import { XMarkIcon, Bars3Icon } from '@heroicons/react/24/outline';
+import Avatar from './ui/atoms/Avator';
+import defaultAvatar from '@/assets/DefaultAvatar.svg';
+import { useNavigate } from 'react-router';
+import { logout } from '@/hooks/userSlice';
+import { useSelector, useDispatch } from 'react-redux';
+import { RootState } from '@/store/rootReducer';
+import { removeToken } from '@/utils/token';
+
+const MenuButton = () => {
+ const [isOpen, setIsOpen] = useState(false);
+ const navigate = useNavigate();
+ const dispatch = useDispatch();
+ const isLoggedIn = useSelector((state: RootState) => state.user.isLoggedIn);
+ const role = useSelector((state: RootState) => state.user.userInfo?.role);
+
+ const handleMyPage = () => {
+ setIsOpen(false);
+ navigate('/mypage');
+ };
+
+ const handleAdminPage = () => {
+ setIsOpen(false);
+ navigate('/adminpage');
+ };
+
+ const handleLogin = () => {
+ setIsOpen(false);
+ navigate('/login');
+ };
+
+ const handleLogout = () => {
+ dispatch(logout());
+ removeToken();
+ setIsOpen(false);
+ navigate('/');
+ };
+
+ const toggleMenu = () => {
+ setIsOpen((prev) => !prev);
+ };
+
+ const nickname = useSelector(
+ (state: RootState) => state.user.userInfo?.nickname
+ );
+
+ return (
+
+
+ {isOpen ? (
+
+ ) : (
+
+ )}
+
+
+ {isOpen && (
+
+
+ {
+ setIsOpen(false);
+ if (isLoggedIn) {
+ role === 'admin'
+ ? navigate('/adminpage')
+ : navigate('/mypage');
+ } else {
+ handleLogin();
+ }
+ }}
+ >
+
+
+ {isLoggedIn ? nickname : '로그인'}
+
+
+ {isLoggedIn ? (
+ <>
+ {role === 'admin' ? (
+ 관리자페이지
+ ) : (
+ 마이페이지
+ )}
+ 문의하기
+ 서비스 소개
+ 로그아웃
+ >
+ ) : (
+ <>
+ 문의하기
+ 서비스 소개
+ >
+ )}
+
+
+ )}
+
+ );
+};
+
+export default MenuButton;
+
+const DropdownContainer = styled.div`
+ position: relative;
+`;
+
+const Button = styled.button`
+ background: none;
+ border: none;
+ cursor: pointer;
+
+ .icon {
+ width: 30px;
+ height: 30px;
+ color: #333;
+ }
+`;
+
+const DropdownMenu = styled.div`
+ position: absolute;
+ top: 100%;
+ right: 0;
+ width: 250px;
+ background-color: white;
+ box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
+ border: 1px solid #ddd;
+ z-index: 100;
+
+ ul {
+ list-style: none;
+ padding: 10px 0;
+ margin: 0;
+
+ li {
+ padding: 10px 15px;
+ cursor: pointer;
+ font-weight: bold;
+ display: flex;
+ align-items: center;
+
+ &:hover {
+ background-color: #f3f3f3;
+ }
+ }
+ }
+`;
+
+const AvatarContainer = styled.div`
+ display: flex;
+ align-items: center;
+ gap: 10px;
+`;
diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx
new file mode 100644
index 0000000..f5005af
--- /dev/null
+++ b/src/components/layout/Layout.tsx
@@ -0,0 +1,22 @@
+import { Outlet } from 'react-router';
+import styled from 'styled-components';
+import Header from '../Header';
+
+const Layout = () => {
+ return (
+
+
+
+
+ );
+};
+
+export default Layout;
+
+const LayoutContainer = styled.div`
+ width: 1000px;
+ margin: 0 auto;
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+`;
diff --git a/src/components/main-page/MainTagList.tsx b/src/components/main-page/MainTagList.tsx
new file mode 100644
index 0000000..f4dabe0
--- /dev/null
+++ b/src/components/main-page/MainTagList.tsx
@@ -0,0 +1,60 @@
+import { useMainTags } from '@/hooks/useMainTags';
+import { useSearchParams } from 'react-router';
+import styled from 'styled-components';
+
+const MainTagList = () => {
+ const { maintags } = useMainTags();
+ const [searchParams, setSearchParams] = useSearchParams();
+
+ const handleTags = (id: number | null) => {
+ const newSearchParams = new URLSearchParams(searchParams);
+ if (id === null) {
+ newSearchParams.delete('id');
+ } else {
+ newSearchParams.set('id', id.toString());
+ }
+ setSearchParams(newSearchParams);
+ };
+
+ return (
+
+ {maintags.map((tag) => (
+ handleTags(tag.id)}
+ >
+ {tag.name}
+
+ ))}
+
+ );
+};
+
+const MainTagListContainer = styled.div`
+ display: flex;
+ justify-content: space-evenly;
+ align-items: center;
+`;
+
+const TagButton = styled.button`
+ border-radius: 30px;
+ font-size: 1.1rem;
+ background-color: transparent;
+ color: #32c040;
+ border: 1px solid #32c040;
+ padding: 8px 20px;
+ text-decoration: none;
+ cursor: pointer;
+ transition: all 0.12s ease-in-out;
+
+ &:hover {
+ background-color: rgba(49, 191, 63, 0.23);
+ }
+
+ &.active {
+ background-color: rgba(49, 191, 63, 0.23);
+ }
+`;
+
+export default MainTagList;
diff --git a/src/components/main-page/QuestionBox.tsx b/src/components/main-page/QuestionBox.tsx
new file mode 100644
index 0000000..664caf0
--- /dev/null
+++ b/src/components/main-page/QuestionBox.tsx
@@ -0,0 +1,64 @@
+import { useEffect, useState } from 'react';
+import styled from 'styled-components';
+import QuestionBody from '../ui/molecules/mainpage-molecule/QuestionBody';
+import QuestionHeader from '../ui/molecules/mainpage-molecule/QuestionHeader';
+import QuestionTag from '../ui/atoms/mainpage-atom/QuesitonTag';
+import QuestionBottom from '../ui/molecules/mainpage-molecule/QuestionBottom';
+import { fetchMainData } from '@/apis/maindata.api';
+import { mainPosts } from '@/types/main.model';
+
+const QuestionBoxContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ margin-top: 30px;
+ gap: 30px;
+`;
+
+const QuestionItem = styled.div`
+ margin: 10px;
+`;
+
+function QuestionBox() {
+ const [posts, setPosts] = useState([]);
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(null);
+
+ useEffect(() => {
+ const loadPosts = async () => {
+ try {
+ const data = await fetchMainData();
+ setPosts(data.posts);
+ } catch (err) {
+ setError('데이터를 불러오는 중 오류가 발생했습니다.');
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ loadPosts();
+ }, []);
+
+ if (loading) return 데이터를 불러오는 중...
;
+ if (error) return {error}
;
+
+ return (
+
+ {posts.map((post) => (
+
+
+
+ {post.tags && }
+
+
+ ))}
+
+ );
+}
+
+export default QuestionBox;
diff --git a/src/components/main-page/SearchInput.tsx b/src/components/main-page/SearchInput.tsx
new file mode 100644
index 0000000..8072832
--- /dev/null
+++ b/src/components/main-page/SearchInput.tsx
@@ -0,0 +1,50 @@
+import { useState } from 'react';
+import styled from 'styled-components';
+import { MagnifyingGlassIcon as SearchIcon} from '@heroicons/react/24/outline';
+const SearchInput = () => {
+ const [searchText, setSearchText] = useState('');
+ const handleSearchChange = (e:React.ChangeEvent) => {
+ const inputText = e.target.value;
+ setSearchText(inputText);
+ }
+ return (
+
+
+
+
+ );
+}
+
+const SearchInputStyle = styled.div`
+ margin: 0 auto;
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 20px;
+ padding: 8px 20px;
+ border: 1px solid #727272;
+ border-radius: 30px;
+ width: 70%;
+
+ input {
+ width: 95%;
+ font-size: 1.2rem;
+ font-weight: 500;
+ border: 0;
+ padding: 5px;
+ }
+
+ button {
+ background-color: transparent;
+ border: 0;
+ margin-left: 10px;
+ cursor: pointer;
+ svg {
+ width: 24px;
+ height: 24px;
+ }
+ }
+
+
+`;
+
+export default SearchInput;
\ No newline at end of file
diff --git a/src/components/my-page/Scraps.tsx b/src/components/my-page/Scraps.tsx
new file mode 100644
index 0000000..97bd8ea
--- /dev/null
+++ b/src/components/my-page/Scraps.tsx
@@ -0,0 +1,88 @@
+import { Post, fetchUserLikes } from '@/apis/user-info.api';
+import { RootState } from '@/store/rootReducer';
+import { useEffect, useState } from 'react';
+import { useSelector } from 'react-redux';
+import styled from 'styled-components';
+import QuestionHeader from '../ui/molecules/mainpage-molecule/QuestionHeader';
+import QuestionBody from '../ui/molecules/mainpage-molecule/QuestionBody';
+import QuestionTag from '../ui/atoms/mainpage-atom/QuesitonTag';
+import QuestionBottom from '../ui/molecules/mainpage-molecule/QuestionBottom';
+
+const Scraps = () => {
+ const nickname = useSelector(
+ (state: RootState) => state.user.userInfo?.nickname
+ );
+
+ const [userData, setUserData] = useState([]);
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ if (nickname) {
+ setLoading(true);
+ fetchUserLikes(nickname)
+ .then((posts) => {
+ setUserData(posts);
+ setLoading(false);
+ })
+ .catch((error) => {
+ console.error('에러 발생:', error);
+ setLoading(false);
+ });
+ }
+ }, [nickname]);
+
+ if (loading) {
+ return Loading...
;
+ }
+
+ if (!userData.length) {
+ return 좋아요한 게시글이 없습니다.
;
+ }
+
+ return (
+
+ 좋아요한 게시글
+
+ {userData.map((post) => (
+
+
+
+ {post.tags && }
+
+
+ ))}
+
+
+ );
+};
+
+export default Scraps;
+
+const ScrapContainer = styled.div`
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+`;
+
+const ScrapTitle = styled.div`
+ width: 100%;
+ height: 40px;
+ padding: 5px 0px 10px 10px;
+ font-size: 30px;
+`;
+
+const QuestionBoxContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 30px;
+`;
+
+const QuestionItem = styled.div`
+ margin: 10px;
+`;
diff --git a/src/components/my-page/UserContents.tsx b/src/components/my-page/UserContents.tsx
new file mode 100644
index 0000000..58ed2a3
--- /dev/null
+++ b/src/components/my-page/UserContents.tsx
@@ -0,0 +1,90 @@
+import { UserData, fetchUserInfo } from '@/apis/user-info.api';
+import { RootState } from '@/store/rootReducer';
+import { useEffect, useState } from 'react';
+import { useSelector } from 'react-redux';
+import styled from 'styled-components';
+import DOMPurify from 'dompurify';
+import Button from '../ui/atoms/Button';
+import { useNavigate } from 'react-router';
+
+const UserContents = () => {
+ const navigate = useNavigate();
+ const nickname = useSelector(
+ (state: RootState) => state.user.userInfo?.nickname
+ );
+
+ const [userData, setUserData] = useState(null);
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ if (nickname) {
+ setLoading(true);
+ fetchUserInfo(nickname)
+ .then((data) => {
+ setUserData(data);
+ setLoading(false);
+ })
+ .catch((error) => {
+ console.error('에러 발생:', error);
+ setLoading(false);
+ });
+ }
+ }, [nickname]);
+
+ if (loading) {
+ return Loading...
;
+ }
+
+ const sanitizedIntroduce = userData?.profile.introduce
+ ? DOMPurify.sanitize(userData.profile.introduce)
+ : '';
+
+ return (
+
+
+ 소개
+ navigate('/boardModification')}
+ >
+ {sanitizedIntroduce ? '소개 수정' : '소개 작성'}
+
+
+
+
+ );
+};
+
+export default UserContents;
+
+const ContentSection = styled.div`
+ width: 100%;
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+`;
+
+const ContentTitle = styled.div`
+ width: 100%;
+ height: 40px;
+ padding: 5px 0px 5px 0px;
+ font-size: 30px;
+`;
+
+const ContentWrapper = styled.div`
+ width: 100%;
+ padding: 10px;
+ border: 1px solid black;
+ border-radius: 5px;
+ background-color: white;
+`;
+
+const ContentHeaderSection = styled.div`
+ display: flex;
+ justify-content: space-between;
+ width: 100%;
+ height: 40px;
+`;
diff --git a/src/components/my-page/UserPosts.tsx b/src/components/my-page/UserPosts.tsx
new file mode 100644
index 0000000..3223e4e
--- /dev/null
+++ b/src/components/my-page/UserPosts.tsx
@@ -0,0 +1,85 @@
+import { UserData, fetchUserInfo } from '@/apis/user-info.api';
+import { RootState } from '@/store/rootReducer';
+import { useEffect, useState } from 'react';
+import { useSelector } from 'react-redux';
+import styled from 'styled-components';
+import QuestionHeader from '../ui/molecules/mainpage-molecule/QuestionHeader';
+import QuestionBody from '../ui/molecules/mainpage-molecule/QuestionBody';
+import QuestionTag from '../ui/atoms/mainpage-atom/QuesitonTag';
+import QuestionBottom from '../ui/molecules/mainpage-molecule/QuestionBottom';
+
+const UserPosts = () => {
+ const nickname = useSelector(
+ (state: RootState) => state.user.userInfo?.nickname
+ );
+
+ const [userData, setUserData] = useState(null);
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ if (nickname) {
+ setLoading(true);
+ fetchUserInfo(nickname)
+ .then((data) => {
+ setUserData(data);
+ setLoading(false);
+ })
+ .catch((error) => {
+ console.error('에러 발생:', error);
+ setLoading(false);
+ });
+ }
+ }, [nickname]);
+
+ if (loading) {
+ return Loading...
;
+ }
+
+ return (
+
+ 작성한 게시글
+
+ {userData &&
+ userData.posts.map((post) => (
+
+
+
+ {post.tags && }
+
+
+ ))}
+
+
+ );
+};
+
+export default UserPosts;
+
+const ScrapContainer = styled.div`
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+`;
+
+const ScrapTitle = styled.div`
+ width: 100%;
+ height: 40px;
+ padding: 5px 0px 10px 10px;
+ font-size: 30px;
+`;
+
+const QuestionBoxContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 30px;
+`;
+
+const QuestionItem = styled.div`
+ margin: 10px;
+`;
diff --git a/src/components/ui/atoms/Avator.stories.tsx b/src/components/ui/atoms/Avator.stories.tsx
new file mode 100644
index 0000000..b928162
--- /dev/null
+++ b/src/components/ui/atoms/Avator.stories.tsx
@@ -0,0 +1,28 @@
+import type { Meta, StoryObj } from '@storybook/react';
+import Avatar from './Avator';
+
+const meta: Meta = {
+ title: 'Components/Atoms/Avatar',
+ component: Avatar,
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {
+ args: {
+ size: 'big',
+ src: 'https://jmagazine.joins.com/_data2/photo/2021/04/838745483_Kw79V5Pa_3.jpg',
+ alt: 'Default Avatar',
+ },
+ render: (args) => ,
+};
+
+export const Outlined: Story = {
+ args: {
+ size: 'small',
+ src: 'https://jmagazine.joins.com/_data2/photo/2021/04/838745483_D5lXOQuU_5.jpg',
+ alt: 'Outlined Avatar',
+ },
+ render: (args) => ,
+};
diff --git a/src/components/ui/atoms/Avator.tsx b/src/components/ui/atoms/Avator.tsx
new file mode 100644
index 0000000..2f493a4
--- /dev/null
+++ b/src/components/ui/atoms/Avator.tsx
@@ -0,0 +1,47 @@
+import styled from 'styled-components';
+
+interface AvatarProps {
+ size?: 'big' | 'small';
+ disabled?: boolean;
+ src: string;
+ alt?: string;
+}
+
+const cx = (...classes: (string | boolean | undefined)[]) =>
+ classes.filter(Boolean).join(' ');
+
+const styles = {
+ base: `
+ display: inline-block;
+ border-radius: 50%;
+ overflow: hidden;
+ object-fit: cover;
+ `,
+ big: `
+ width: 200px;
+ height: 200px;
+ `,
+ small: `
+ width: 48px;
+ height: 48px;
+ `,
+ disabled: `
+ opacity: 0.5;
+ pointer-events: none;
+ `,
+};
+
+const Avatar = styled.img.attrs(({ src, alt }) => ({
+ src,
+ alt: alt || 'Avatar',
+}))`
+ ${({ size, disabled }) =>
+ cx(
+ styles.base,
+ size === 'big' && styles.big,
+ size === 'small' && styles.small,
+ disabled && styles.disabled
+ )}
+`;
+
+export default Avatar;
diff --git a/src/components/ui/atoms/Button.ts b/src/components/ui/atoms/Button.ts
new file mode 100644
index 0000000..702dbac
--- /dev/null
+++ b/src/components/ui/atoms/Button.ts
@@ -0,0 +1,62 @@
+import styled from 'styled-components';
+
+interface ButtonProps {
+ variant?: 'primary' | 'outline' | 'tag';
+ disabled?: boolean;
+ customStyle?: string;
+}
+
+const cx = (...classes: (string | boolean | undefined)[]) =>
+ classes.filter(Boolean).join(' ');
+
+const styles = {
+ base: `
+ font-size: 1em;
+ padding: 0.5em 1em;
+ border-radius: 5px;
+ cursor: pointer;
+ `,
+ primary: `
+ background-color: mediumseagreen;
+ color: white;
+ border: black;
+ height: 30px;
+ padding: 5px;
+ `,
+ tag: `
+ background-color: white;
+ border: 1px solid mediumseagreen;
+ height: 30px;
+ padding: 5px;
+ color: mediumseagreen;
+ `,
+ outline: `
+ background-color: white;
+ color: mediumseagreen;
+ border: 2px solid mediumseagreen;
+
+ &:hover {
+ background-color: mediumseagreen;
+ color: white;
+ }
+ `,
+ disabled: `
+ background-color: #ccc;
+ color: #666;
+ cursor: not-allowed;
+ `,
+};
+
+const Button = styled.button`
+ ${({ variant, disabled, customStyle }) =>
+ cx(
+ styles.base,
+ variant === 'primary' && styles.primary,
+ variant === 'outline' && styles.outline,
+ variant === 'tag' && styles.tag,
+ disabled && styles.disabled,
+ customStyle
+ )}
+`;
+
+export default Button;
diff --git a/src/components/ui/atoms/Input.tsx b/src/components/ui/atoms/Input.tsx
new file mode 100644
index 0000000..bc6de15
--- /dev/null
+++ b/src/components/ui/atoms/Input.tsx
@@ -0,0 +1,89 @@
+import React, { ForwardedRef, useState } from 'react';
+import styled from 'styled-components';
+
+interface InputFieldProps extends React.InputHTMLAttributes {
+ label: string;
+ inputType?: 'text' | 'email' | 'password' | 'number' | 'nickname';
+}
+
+const Container = styled.div`
+ position: relative;
+ width: 100%;
+ align-items: center;
+ margin-top: 1.5rem;
+ justify-content: center;
+`;
+
+interface LabelProps {
+ isActive: boolean;
+}
+
+const StyledLabel = styled.label`
+ position: absolute;
+ left: 2rem;
+ top: 50%;
+ transform: translateY(-50%);
+ color: #727272;
+ font-family: sans-serif;
+ transition: all 0.2s ease-in-out;
+
+ ${({ isActive }) =>
+ isActive &&
+ `
+ top: 25%;
+ font-size: 0.75rem; /* text-xs */
+ color: #6b7280; /* text-gray-500 */
+ `}
+`;
+
+const StyledInput = styled.input`
+ align-items: center;
+ width: 100%;
+ height: 70px;
+ padding: 0.1rem 1rem;
+ background-color: #ffffff;
+ border-radius: 0.375rem;
+ border: 0.5px solid #000000;
+ color: #727272;
+ font-size: 1.25rem;
+
+ &:focus {
+ outline: none;
+ }
+
+ ::placeholder {
+ color: transparent;
+ }
+`;
+
+const Input = React.forwardRef(
+ (
+ { label, inputType = 'text', onChange, ...props }: InputFieldProps,
+ ref: ForwardedRef
+ ) => {
+ const [isFocused, setIsFocused] = useState(false);
+ const [hasValue, setHasValue] = useState(false);
+
+ const handleInputFocus = () => setIsFocused(true);
+ const handleInputBlur = (e: React.ChangeEvent) => {
+ setIsFocused(false);
+ setHasValue(e.target.value !== '');
+ };
+
+ return (
+
+ {label}
+
+
+ );
+ }
+);
+
+export default Input;
diff --git a/src/components/ui/atoms/join-atom/PasswordGuideLines.tsx b/src/components/ui/atoms/join-atom/PasswordGuideLines.tsx
new file mode 100644
index 0000000..f5f03be
--- /dev/null
+++ b/src/components/ui/atoms/join-atom/PasswordGuideLines.tsx
@@ -0,0 +1,87 @@
+import { useEffect, useState } from 'react';
+import { CheckCircleIcon } from '@heroicons/react/20/solid';
+import styled from 'styled-components';
+
+interface Guideline {
+ label: string;
+ isValid: boolean;
+ check: (password: string) => boolean;
+}
+
+const Container = styled.div`
+ display: flex;
+ flex-direction: column;
+ > * + * {
+ margin-top: 0.5rem;
+ }
+`;
+
+const GuidelineItem = styled.div`
+ display: flex;
+ align-items: center;
+`;
+
+const StyledCheckCircleIcon = styled(CheckCircleIcon)`
+ width: 1.25rem;
+ height: 1.25rem;
+ color: #32c040;
+`;
+
+const EmptyCircle = styled.span`
+ margin-left: 0.15rem;
+ width: 0.85rem;
+ height: 0.85rem;
+ border: 1px solid #374151;
+ border-radius: 9999px;
+ display: inline-block;
+`;
+
+const GuidelineLabel = styled.span<{ isValid: boolean }>`
+ margin-left: 0.5rem;
+ font-size: 0.875rem;
+ color: ${(props) => (props.isValid ? '#32C040' : '#6b7280')};
+`;
+
+const PasswordGuideLines = ({ password }: { password: string }) => {
+ const [guidelines, setGuidelines] = useState([
+ {
+ label: '8자 이상, 15자 이하로 설정해 주세요',
+ isValid: false,
+ check: (password: string) =>
+ password.length >= 8 && password.length <= 15,
+ },
+ {
+ label: '특수 문자를 사용해 주세요',
+ isValid: false,
+ check: (password: string) => /[!@#$%^&*(),.?":{}|<>]/.test(password),
+ },
+ {
+ label: '동일한 문자가 4번 반복되면 안돼요',
+ isValid: false,
+ check: (password: string) =>
+ !/(.)\1{3}/.test(password.replace(/\s/g, '')),
+ },
+ ]);
+
+ useEffect(() => {
+ setGuidelines((prevGuidelines) =>
+ prevGuidelines.map((guideline) => ({
+ ...guideline,
+ isValid: guideline.check(password),
+ }))
+ );
+ }, [password]);
+
+ return (
+
+ {guidelines.map(({ label, isValid }, index) => (
+
+ {isValid ? : }
+ {label}
+
+ ))}
+
+ );
+};
+
+export default PasswordGuideLines;
diff --git a/src/components/ui/atoms/mainpage-atom/QuesitonTag.tsx b/src/components/ui/atoms/mainpage-atom/QuesitonTag.tsx
new file mode 100644
index 0000000..dcd267e
--- /dev/null
+++ b/src/components/ui/atoms/mainpage-atom/QuesitonTag.tsx
@@ -0,0 +1,34 @@
+import styled from 'styled-components';
+
+// Styled Components
+const TagsContainer = styled.div`
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-top: 12px;
+`;
+
+const TagItem = styled.div`
+ background-color: #deffe2;
+ color: #858585;
+ font-family: 'Pretendard-Light', Helvetica;
+ font-size: 12px;
+ padding: 8px 16px;
+ border-radius: 12px;
+`;
+
+interface TagsProps {
+ tags: string[];
+}
+
+function QuestionTag({ tags }: TagsProps) {
+ return (
+
+ {tags.map((tag, index) => (
+ {tag}
+ ))}
+
+ );
+}
+
+export default QuestionTag;
diff --git a/src/components/ui/atoms/mainpage-atom/QuestionButton.tsx b/src/components/ui/atoms/mainpage-atom/QuestionButton.tsx
new file mode 100644
index 0000000..b584ecd
--- /dev/null
+++ b/src/components/ui/atoms/mainpage-atom/QuestionButton.tsx
@@ -0,0 +1,97 @@
+import styled from 'styled-components';
+
+const ProblemBox = styled.div`
+ height: 20px;
+ width: 77px;
+
+ .group {
+ height: 20px;
+ left: 0;
+ position: relative; /* fixed → relative로 수정 */
+ top: 0;
+ }
+
+ .overlap-group {
+ background-color: #d9d9d9;
+ border-radius: 30px;
+ height: 30px;
+ position: relative;
+ width: 100px;
+ }
+
+ .text-wrapper {
+ color: #ffffff;
+ font-family: 'Pretendard-ExtraBold', Helvetica;
+ font-size: 15px;
+ left: 20px;
+ line-height: 20px;
+ position: absolute;
+ text-align: center;
+ top: 3px;
+ white-space: nowrap;
+ width: 50px;
+ }
+`;
+
+const SolveBox = styled.div`
+ height: 20px;
+ width: 77px;
+
+ .group {
+ height: 20px;
+ left: 0;
+ position: relative; /* fixed → relative로 수정 */
+ top: 0;
+ }
+
+ .overlap-group {
+ background-color: #c9ffce;
+ border-radius: 30px;
+ height: 30px;
+ position: relative;
+ width: 100px;
+ }
+
+ .text-wrapper {
+ color: #007c0c;
+ font-family: 'Pretendard-ExtraBold', Helvetica;
+ font-size: 15px;
+ left: 25px;
+ line-height: 20px;
+ position: absolute;
+ text-align: center;
+ top: 4px;
+ white-space: nowrap;
+ width: 50px;
+ }
+`;
+
+export const ProblemButton = () => {
+ return (
+
+
+
+ );
+};
+
+export const SolveButton = () => {
+ return (
+
+
+
+ );
+};
+
+const QuestionButton = ({ solved }: { solved: number }) => {
+ return solved === 1 ? : ;
+};
+
+export default QuestionButton;
diff --git a/src/components/ui/atoms/mainpage-atom/QuestionTitle.tsx b/src/components/ui/atoms/mainpage-atom/QuestionTitle.tsx
new file mode 100644
index 0000000..0075131
--- /dev/null
+++ b/src/components/ui/atoms/mainpage-atom/QuestionTitle.tsx
@@ -0,0 +1,19 @@
+import styled from 'styled-components';
+
+const TitleContainer = styled.div`
+ font-family: 'Pretendard-SemiBold', Helvetica;
+ font-size: 18px;
+ color: #000;
+ margin-top: 5px;
+ margin-left: 30px;
+`;
+
+interface TitleProps {
+ text: string;
+}
+
+function QuestionTitle({ text }: TitleProps) {
+ return {text} ;
+}
+
+export default QuestionTitle;
diff --git a/src/components/ui/atoms/mainpage-atom/QuestionUser.tsx b/src/components/ui/atoms/mainpage-atom/QuestionUser.tsx
new file mode 100644
index 0000000..58cd5f0
--- /dev/null
+++ b/src/components/ui/atoms/mainpage-atom/QuestionUser.tsx
@@ -0,0 +1,26 @@
+import styled from 'styled-components';
+
+const UserContainer = styled.div`
+ font-family: 'Pretendard-ExtraLight', Helvetica;
+ font-size: 12px;
+ color: #666;
+ display: flex;
+ gap: 8px;
+ margin-left: 5px;
+`;
+
+interface QuestionUserProps {
+ nickname: string;
+ time: string;
+}
+
+function QuestionUser({ nickname, time }: QuestionUserProps) {
+ return (
+
+ {nickname}
+ {time}
+
+ );
+}
+
+export default QuestionUser;
diff --git a/src/components/ui/atoms/mainpage-atom/QuestionUtil.tsx b/src/components/ui/atoms/mainpage-atom/QuestionUtil.tsx
new file mode 100644
index 0000000..f514bc9
--- /dev/null
+++ b/src/components/ui/atoms/mainpage-atom/QuestionUtil.tsx
@@ -0,0 +1,56 @@
+import styled from 'styled-components';
+import {
+ ChatBubbleOvalLeftEllipsisIcon,
+ EyeIcon,
+} from '@heroicons/react/24/outline';
+import { HeartIcon as SolidHeartIcon } from '@heroicons/react/24/solid';
+
+// Styled Components
+const UtilContainer = styled.div`
+ display: flex;
+ gap: 12px;
+ font-family: 'Pretendard-ExtraLight', Helvetica;
+ font-size: 13px;
+ color: #666;
+ margin-right: 5px;
+`;
+
+const IconWrapper = styled.span`
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ cursor: pointer;
+ user-select: none;
+
+ svg {
+ width: 16px;
+ height: 16px;
+ }
+`;
+
+interface QuestionUtilProps {
+ likes: number;
+ comments: number;
+ views: number;
+}
+
+function QuestionUtil({ likes, comments, views }: QuestionUtilProps) {
+ return (
+
+
+
+ {likes}
+
+
+
+ {comments}
+
+
+
+ {views}
+
+
+ );
+}
+
+export default QuestionUtil;
diff --git a/src/components/ui/molecules/QuillEditor.tsx b/src/components/ui/molecules/QuillEditor.tsx
new file mode 100644
index 0000000..1ed47b6
--- /dev/null
+++ b/src/components/ui/molecules/QuillEditor.tsx
@@ -0,0 +1,45 @@
+import React, { useRef } from 'react';
+import ReactQuill, { Quill } from 'react-quill';
+import 'react-quill/dist/quill.snow.css';
+
+interface RichTextEditorProps {
+ value: string;
+ onChange: (value: string) => void;
+}
+
+const RichTextEditor: React.FC = ({ value, onChange }) => {
+ const quillRef = useRef(null); // React ref 사용
+
+ const modules = {
+ toolbar: [
+ [{ header: [1, 2, false] }],
+ ['bold', 'italic', 'underline', 'strike'],
+ [{ list: 'ordered' }, { list: 'bullet' }],
+ ['code-block'],
+ ],
+ };
+
+ const formats = [
+ 'header',
+ 'bold',
+ 'italic',
+ 'underline',
+ 'strike',
+ 'list',
+ 'bullet',
+ 'code-block',
+ ];
+
+ return (
+
+ );
+};
+
+export default RichTextEditor;
diff --git a/src/components/ui/molecules/mainpage-molecule/QuestionBody.tsx b/src/components/ui/molecules/mainpage-molecule/QuestionBody.tsx
new file mode 100644
index 0000000..12f73ba
--- /dev/null
+++ b/src/components/ui/molecules/mainpage-molecule/QuestionBody.tsx
@@ -0,0 +1,21 @@
+import styled from 'styled-components';
+
+const BodyContainer = styled.div`
+ font-family: 'Pretendard-Light', Helvetica;
+ font-size: 15px;
+ margin-left: 5px;
+ line-height: 1.5;
+ color: #333;
+ margin-top: 20px;
+ margin-right: 5px;
+`;
+
+interface QuestionBodyProps {
+ content: string;
+}
+
+function QuestionBody({ content }: QuestionBodyProps) {
+ return {content} ;
+}
+
+export default QuestionBody;
diff --git a/src/components/ui/molecules/mainpage-molecule/QuestionBottom.tsx b/src/components/ui/molecules/mainpage-molecule/QuestionBottom.tsx
new file mode 100644
index 0000000..810b3e8
--- /dev/null
+++ b/src/components/ui/molecules/mainpage-molecule/QuestionBottom.tsx
@@ -0,0 +1,35 @@
+import styled from 'styled-components';
+import QuestionUser from '../../atoms/mainpage-atom/QuestionUser';
+import QuestionUtil from '../../atoms/mainpage-atom/QuestionUtil';
+
+const BottomContainer = styled.div`
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-top: 12px;
+`;
+
+interface QuestionBottomProps {
+ nickname: string;
+ time: string;
+ likes: number;
+ comments: number;
+ views: number;
+}
+
+function QuestionBottom({
+ nickname,
+ time,
+ likes,
+ comments,
+ views,
+}: QuestionBottomProps) {
+ return (
+
+
+
+
+ );
+}
+
+export default QuestionBottom;
diff --git a/src/components/ui/molecules/mainpage-molecule/QuestionHeader.tsx b/src/components/ui/molecules/mainpage-molecule/QuestionHeader.tsx
new file mode 100644
index 0000000..28a4110
--- /dev/null
+++ b/src/components/ui/molecules/mainpage-molecule/QuestionHeader.tsx
@@ -0,0 +1,25 @@
+import styled from 'styled-components';
+import QuestionButton from '../../atoms/mainpage-atom/QuestionButton';
+import QuestionTitle from '../../atoms/mainpage-atom/QuestionTitle';
+
+const HeaderContainer = styled.div`
+ display: flex;
+ align-items: center;
+ gap: 8px;
+`;
+
+interface QuestionHeaderProps {
+ solved: number;
+ title: string;
+}
+
+function QuestionHeader({ solved, title }: QuestionHeaderProps) {
+ return (
+
+
+
+
+ );
+}
+
+export default QuestionHeader;
diff --git a/src/constants/TagItems.ts b/src/constants/TagItems.ts
new file mode 100644
index 0000000..dd2fb9c
--- /dev/null
+++ b/src/constants/TagItems.ts
@@ -0,0 +1,10 @@
+export const TagItems = [
+ 'Javascript',
+ 'NodeJs',
+ 'HTML',
+ 'CSS',
+ 'React',
+ 'C',
+ 'JAVA',
+ 'Python',
+];
diff --git a/src/custom.d.ts b/src/custom.d.ts
new file mode 100644
index 0000000..7458a9b
--- /dev/null
+++ b/src/custom.d.ts
@@ -0,0 +1,7 @@
+declare module '*.svg' {
+ import React = require('react');
+
+ export const ReactComponent: React.FC>;
+ const src: string;
+ export default src;
+}
diff --git a/src/hooks/useMainTags.ts b/src/hooks/useMainTags.ts
new file mode 100644
index 0000000..795a41b
--- /dev/null
+++ b/src/hooks/useMainTags.ts
@@ -0,0 +1,48 @@
+import { fetchMainData } from '@/apis/maindata.api';
+import { mainTags } from '@/types/main.model';
+import { useEffect, useState } from 'react';
+import { useLocation } from 'react-router';
+
+export const useMainTags = () => {
+ const location = useLocation();
+ const [maintags, setMaintags] = useState([]);
+
+ const setActive = () => {
+ const params = new URLSearchParams(location.search);
+ if (params.get('id')) {
+ setMaintags((prev) => {
+ return prev.map((item) => {
+ return { ...item, isActive: item.id === Number(params.get('id')) };
+ });
+ });
+ } else {
+ setMaintags((prev) => {
+ return prev.map((item) => {
+ return { ...item, isActive: false };
+ });
+ });
+ }
+ };
+
+ useEffect(() => {
+ fetchMainData().then((data) => {
+ if (!data.tags) return;
+ const tagsAll = [
+ {
+ id: null,
+ name: '전체',
+ },
+ ...data.tags,
+ ];
+
+ setMaintags(tagsAll);
+ setActive();
+ });
+ }, []);
+
+ useEffect(() => {
+ setActive();
+ }, [location.search]);
+
+ return { maintags };
+};
diff --git a/src/hooks/useRichTextViewer.tsx b/src/hooks/useRichTextViewer.tsx
new file mode 100644
index 0000000..475881c
--- /dev/null
+++ b/src/hooks/useRichTextViewer.tsx
@@ -0,0 +1,13 @@
+import DOMPurify from 'dompurify';
+
+const RichTextViewer = ({ content }: { content: string }) => {
+ const sanitizedContent = DOMPurify.sanitize(content);
+ return (
+
+ );
+};
+
+export default RichTextViewer;
diff --git a/src/hooks/userSlice.ts b/src/hooks/userSlice.ts
new file mode 100644
index 0000000..882cabb
--- /dev/null
+++ b/src/hooks/userSlice.ts
@@ -0,0 +1,85 @@
+import { DecodedToken, UserInfo, UserState } from '@/types/auth';
+import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit';
+import axios from 'axios';
+import { jwtDecode } from 'jwt-decode';
+import { BASE_URL } from '@/apis/http.api';
+
+const initialState: UserState = {
+ isLoggedIn: false,
+ token: null,
+ userInfo: null,
+ loading: false,
+ error: null,
+};
+
+export const loginAsync = createAsyncThunk(
+ 'user/loginAsync',
+ async (
+ { email, password }: { email: string; password: string },
+ { rejectWithValue }
+ ) => {
+ try {
+ const response = await axios.post(`${BASE_URL}/api/users/login`, {
+ email,
+ password,
+ });
+
+ if (response.data.success && response.data.token) {
+ return response.data.token;
+ } else {
+ return rejectWithValue('로그인 실패: 토큰 없음');
+ }
+ } catch (error: any) {
+ return rejectWithValue(
+ error.response?.data?.message || '로그인 요청 실패'
+ );
+ }
+ }
+);
+
+const userSlice = createSlice({
+ name: 'user',
+ initialState,
+ reducers: {
+ logout: (state) => {
+ state.isLoggedIn = false;
+ state.token = null;
+ state.userInfo = null;
+ state.loading = false;
+ state.error = null;
+ },
+ },
+ extraReducers: (builder) => {
+ builder
+ .addCase(loginAsync.pending, (state) => {
+ state.loading = true;
+ state.error = null;
+ })
+ .addCase(loginAsync.fulfilled, (state, action) => {
+ const decoded: DecodedToken = jwtDecode(action.payload);
+ const userInfo: UserInfo = {
+ id: decoded.id,
+ email: decoded.email,
+ nickname: decoded.nickname,
+ role: decoded.role,
+ };
+
+ state.isLoggedIn = true;
+ state.token = action.payload;
+ state.userInfo = userInfo;
+ state.loading = false;
+ state.error = null;
+
+ if (typeof window !== 'undefined') {
+ localStorage.setItem('token', action.payload);
+ }
+ })
+ .addCase(loginAsync.rejected, (state, action) => {
+ state.loading = false;
+ state.error = action.payload as string;
+ });
+ },
+});
+
+export const { logout } = userSlice.actions;
+export default userSlice.reducer;
diff --git a/src/index.css b/src/index.css
deleted file mode 100644
index 6119ad9..0000000
--- a/src/index.css
+++ /dev/null
@@ -1,68 +0,0 @@
-:root {
- font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
- line-height: 1.5;
- font-weight: 400;
-
- color-scheme: light dark;
- color: rgba(255, 255, 255, 0.87);
- background-color: #242424;
-
- font-synthesis: none;
- text-rendering: optimizeLegibility;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-a {
- font-weight: 500;
- color: #646cff;
- text-decoration: inherit;
-}
-a:hover {
- color: #535bf2;
-}
-
-body {
- margin: 0;
- display: flex;
- place-items: center;
- min-width: 320px;
- min-height: 100vh;
-}
-
-h1 {
- font-size: 3.2em;
- line-height: 1.1;
-}
-
-button {
- border-radius: 8px;
- border: 1px solid transparent;
- padding: 0.6em 1.2em;
- font-size: 1em;
- font-weight: 500;
- font-family: inherit;
- background-color: #1a1a1a;
- cursor: pointer;
- transition: border-color 0.25s;
-}
-button:hover {
- border-color: #646cff;
-}
-button:focus,
-button:focus-visible {
- outline: 4px auto -webkit-focus-ring-color;
-}
-
-@media (prefers-color-scheme: light) {
- :root {
- color: #213547;
- background-color: #ffffff;
- }
- a:hover {
- color: #747bff;
- }
- button {
- background-color: #f9f9f9;
- }
-}
diff --git a/src/main.tsx b/src/main.tsx
index bef5202..4ee7573 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -1,10 +1,10 @@
-import { StrictMode } from 'react'
-import { createRoot } from 'react-dom/client'
-import './index.css'
-import App from './App.tsx'
+import { StrictMode } from 'react';
+import { createRoot } from 'react-dom/client';
+import App from './App.tsx';
+import '@/styles/reset.css';
createRoot(document.getElementById('root')!).render(
- ,
-)
+
+);
diff --git a/src/mocks/browser.ts b/src/mocks/browser.ts
new file mode 100644
index 0000000..0a56427
--- /dev/null
+++ b/src/mocks/browser.ts
@@ -0,0 +1,4 @@
+import { setupWorker } from 'msw/browser';
+import { handlers } from './handlers';
+
+export const worker = setupWorker(...handlers);
diff --git a/src/mocks/handlers.ts b/src/mocks/handlers.ts
new file mode 100644
index 0000000..85fe632
--- /dev/null
+++ b/src/mocks/handlers.ts
@@ -0,0 +1,13 @@
+import { http, HttpResponse } from 'msw';
+
+export const handlers = [
+ // Intercept "GET https://example.com/user" requests...
+ http.get('https://example.com/user', () => {
+ // ...and respond to them using this JSON response.
+ return HttpResponse.json({
+ id: 'c7b3d8e0-5e0b-4b0f-8b3a-3b9f4b3d3b3d',
+ firstName: 'John',
+ lastName: 'Maverick',
+ });
+ }),
+];
diff --git a/src/pages/AdminPage.tsx b/src/pages/AdminPage.tsx
new file mode 100644
index 0000000..c2d1874
--- /dev/null
+++ b/src/pages/AdminPage.tsx
@@ -0,0 +1,69 @@
+import { useState } from 'react';
+import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/outline';
+import UserList from '@/admin/UserList';
+import styled from 'styled-components';
+
+// Styled Components
+const PageContainer = styled.div`
+ padding: 20px;
+`;
+
+const TitleContainer = styled.div`
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+ cursor: pointer;
+ margin-left: 10px;
+ margin-right: 10px;
+`;
+
+const Title = styled.h1`
+ font-family: 'Pretendard', sans-serif;
+ font-size: 32px;
+ font-weight: 800;
+ text-align: left;
+ margin: 0;
+`;
+
+const IconWrapper = styled.div`
+ width: 24px;
+ height: 24px;
+ margin-left: 10px;
+`;
+
+const ListContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ width: 100%;
+ margin-top: 40px;
+`;
+
+const AdminPage = () => {
+ const [showUserList, setShowUserList] = useState(false);
+
+ const toggleUserList = () => {
+ setShowUserList((open) => !open);
+ };
+
+ return (
+
+ {/* 제목과 아이콘 */}
+
+ 유저조회
+
+ {showUserList ? : }
+
+
+
+ {/* 유저 리스트 */}
+ {showUserList && (
+
+
+
+ )}
+
+ );
+};
+
+export default AdminPage;
diff --git a/src/pages/BoardModificationPage.tsx b/src/pages/BoardModificationPage.tsx
new file mode 100644
index 0000000..f0c7f93
--- /dev/null
+++ b/src/pages/BoardModificationPage.tsx
@@ -0,0 +1,85 @@
+import { updateUserIntroduce } from '@/apis/board.api';
+import { fetchUserInfo } from '@/apis/user-info.api';
+import Button from '@/components/ui/atoms/Button';
+import RichTextEditor from '@/components/ui/molecules/QuillEditor';
+import { RootState } from '@/store/rootReducer';
+import { useEffect, useState } from 'react';
+import { useSelector } from 'react-redux';
+import styled from 'styled-components';
+
+const BoardModificationPage = () => {
+ const nickname = useSelector(
+ (state: RootState) => state.user.userInfo?.nickname
+ );
+ const id = useSelector((state: RootState) => state.user.userInfo?.id);
+
+ const [content, setContent] = useState('');
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ if (nickname) {
+ setLoading(true);
+ fetchUserInfo(nickname)
+ .then((data) => {
+ setContent(data.profile.introduce);
+ setLoading(false);
+ })
+ .catch((error) => {
+ console.error('에러 발생:', error);
+ setLoading(false);
+ });
+ }
+ }, [nickname]);
+
+ if (loading) {
+ return Loading...
;
+ }
+
+ const registerBoard = async () => {
+ if (!content.trim()) {
+ alert('내용을 입력해주세요.');
+ return;
+ }
+ try {
+ const response = await updateUserIntroduce(id as number, content);
+ console.log('게시글 등록 성공:', response);
+ alert('게시글이 성공적으로 등록되었습니다!');
+ } catch (error) {
+ console.error('게시글 등록 실패:', error);
+ alert('게시글 등록에 실패했습니다. 다시 시도해주세요.');
+ }
+ };
+
+ return (
+
+
+
+
+
+ window.history.back()}>
+ 취소
+
+
+ 등록
+
+
+
+ );
+};
+
+export default BoardModificationPage;
+
+const WriteContainer = styled.div`
+ width: 100%;
+ height: fit-content;
+ border: 2px solid gray;
+ border-radius: 10px;
+ padding: 0px 0px 10px 0px;
+`;
+
+const RegisterSection = styled.div`
+ display: flex;
+ flex-direction: row-reverse;
+ padding: 0px 20px 0px 20px;
+ gap: 10px;
+`;
diff --git a/src/pages/BoardWritePage.tsx b/src/pages/BoardWritePage.tsx
new file mode 100644
index 0000000..0bbd356
--- /dev/null
+++ b/src/pages/BoardWritePage.tsx
@@ -0,0 +1,134 @@
+import { fetchUpdateReview } from '@/apis/board.api';
+import Button from '@/components/ui/atoms/Button';
+import RichTextEditor from '@/components/ui/molecules/QuillEditor';
+import { TagItems } from '@/constants/TagItems';
+import { useState } from 'react';
+import styled from 'styled-components';
+
+const BoardWritePage = () => {
+ const [title, setTitle] = useState('');
+ const [selectedTags, setSelectedTags] = useState([]);
+ const [content, setContent] = useState('');
+
+ const handleTagSelected = (index: number) => {
+ setSelectedTags((prev) =>
+ prev.includes(index) ? prev.filter((i) => i !== index) : [...prev, index]
+ );
+ };
+
+ const registerBoard = async () => {
+ if (!title.trim()) {
+ alert('제목을 입력해주세요.');
+ return;
+ }
+ if (selectedTags.length === 0) {
+ alert('태그를 선택해주세요.');
+ return;
+ }
+ if (!content.trim()) {
+ alert('내용을 입력해주세요.');
+ return;
+ }
+ const selectedTagNames = selectedTags.map((index) => TagItems[index]);
+ try {
+ console.log('title: ', title);
+ const response = await fetchUpdateReview(
+ title,
+ selectedTagNames,
+ content
+ );
+ console.log('게시글 등록 성공:', response);
+ alert('게시글이 성공적으로 등록되었습니다!');
+ } catch (error) {
+ console.error('게시글 등록 실패:', error);
+ alert('게시글 등록에 실패했습니다. 다시 시도해주세요.');
+ }
+ };
+
+ return (
+
+
+ setTitle(e.target.value)}
+ />
+
+
+ 태그를 등록해주세요
+
+ {TagItems.map((item, index) => (
+ handleTagSelected(index)}
+ >
+ {item}
+
+ ))}
+
+
+
+
+
+
+ 취소
+
+ 등록
+
+
+
+ );
+};
+
+export default BoardWritePage;
+
+const WriteContainer = styled.div`
+ width: 100%;
+ height: fit-content;
+ border: 2px solid gray;
+ border-radius: 10px;
+ padding: 0px 0px 10px 0px;
+`;
+
+const TitleSection = styled.div`
+ width: 100%;
+ display: flex;
+ align-items: center;
+ padding: 10px 10px 10px 20px;
+`;
+
+const TitleInput = styled.input`
+ font-size: 22px;
+ height: 44px;
+ width: 500px;
+ border: none;
+ padding: 5px;
+`;
+
+const TagSection = styled.div`
+ width: 100%;
+ height: 70px;
+ display: flex;
+ flex-direction: column;
+ padding: 10px 10px 10px 20px;
+ gap: 5px;
+`;
+
+const TagTitle = styled.div`
+ font-size: 18px;
+ padding-left: 5px;
+`;
+
+const TagWrapper = styled.div`
+ display: flex;
+ gap: 10px;
+ padding-left: 5px;
+`;
+
+const RegisterSection = styled.div`
+ display: flex;
+ flex-direction: row-reverse;
+ padding: 0px 20px 0px 20px;
+ gap: 10px;
+`;
diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx
new file mode 100644
index 0000000..86020db
--- /dev/null
+++ b/src/pages/HomePage.tsx
@@ -0,0 +1,15 @@
+import MainTagList from '@/components/main-page/MainTagList';
+import SearchInput from '@/components/main-page/SearchInput';
+import QuestionBox from '@/components/main-page/QuestionBox';
+
+const HomePage = () => {
+ return (
+
+
+
+
+
+ );
+};
+
+export default HomePage;
diff --git a/src/pages/JoinPage.tsx b/src/pages/JoinPage.tsx
new file mode 100644
index 0000000..651e03a
--- /dev/null
+++ b/src/pages/JoinPage.tsx
@@ -0,0 +1,228 @@
+import { useState } from 'react';
+import { useForm } from 'react-hook-form';
+import styled from 'styled-components';
+import { useNavigate } from 'react-router';
+import qublogo from '@/assets/qublogo.svg';
+import { join } from '@/apis/auth.api';
+import PasswordGuideLines from '@/components/ui/atoms/join-atom/PasswordGuideLines';
+import Input from '@/components/ui/atoms/Input';
+
+export interface JoinProps {
+ email: string;
+ nickname: string;
+ password: string;
+ confirmPassword: string;
+}
+
+function JoinPage() {
+ const navigate = useNavigate();
+ const [isLoading, setIsLoading] = useState(false);
+
+ const {
+ register,
+ handleSubmit,
+ formState: { errors },
+ watch,
+ } = useForm();
+
+ const password = watch('password');
+
+ const onSubmit = async (data: JoinProps) => {
+ setIsLoading(true);
+ try {
+ await join(data);
+ alert('회원가입이 완료되었습니다!');
+ navigate('/login');
+ } catch (error: any) {
+ console.error('회원가입 중 에러 발생:', error);
+ if (error.response?.data?.message) {
+ alert(error.response.data.message);
+ } else {
+ alert('회원가입에 실패했습니다. 다시 시도해주세요.');
+ }
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ return (
+
+
+ navigate('/')}>
+
+
+
+
+
+
+ );
+}
+
+const Container = styled.div`
+ background-color: #ffffff;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ height: 100vh;
+`;
+
+const InnerWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ width: 100%;
+ max-width: 24rem;
+`;
+
+const LogoWrapper = styled.div`
+ margin-bottom: 2.5rem;
+ cursor: pointer;
+`;
+
+const LogoImage = styled.img`
+ width: 150px;
+ height: 80px;
+ object-fit: contain;
+`;
+
+const Form = styled.form`
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+`;
+
+const InputWrapper = styled.div`
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ margin-bottom: 1rem;
+`;
+
+const StyledInput = styled(Input)`
+ max-width: 350px;
+ width: 100%;
+ margin: 0 auto;
+ display: block;
+`;
+
+const PasswordGuideLinesWrapper = styled.div`
+ width: 100%;
+ text-align: left;
+ margin-left: 1rem;
+ margin-top: 1rem;
+ margin-bottom: 1rem;
+`;
+
+const SubmitButton = styled.button`
+ width: 300px;
+ height: 70px;
+ background-color: #ffffff;
+ border: 1px solid #000000;
+ border-radius: 9999px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ color: #000000;
+ font-size: 15px;
+ font-weight: 400;
+ cursor: pointer;
+ margin: 0 auto;
+ margin-top: 2rem;
+
+ &:hover {
+ background-color: #e5e7eb;
+ }
+
+ &:disabled {
+ background-color: #e5e7eb;
+ cursor: not-allowed;
+ }
+`;
+
+const ErrorText = styled.p`
+ color: #ef4444;
+ font-size: 0.875rem;
+ margin-bottom: 1rem;
+ text-align: left;
+ width: 100%;
+ max-width: 350px;
+`;
+
+export default JoinPage;
diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx
new file mode 100644
index 0000000..0c1c3ca
--- /dev/null
+++ b/src/pages/LoginPage.tsx
@@ -0,0 +1,188 @@
+import styled from 'styled-components';
+import { useNavigate } from 'react-router';
+import qublogo from '@/assets/qublogo.svg';
+import { useForm } from 'react-hook-form';
+import { useDispatch, useSelector } from 'react-redux'; // Redux 추가
+import Input from '@/components/ui/atoms/Input';
+import { RootState } from '@/store/rootReducer';
+import { loginAsync } from '@/hooks/userSlice';
+import { AppDispatch } from '@/store/store';
+
+export type LoginFormData = {
+ email: string;
+ password: string;
+};
+
+function LoginPage() {
+ const navigate = useNavigate();
+ const dispatch = useDispatch();
+ const { loading, error } = useSelector((state: RootState) => state.user);
+
+ const {
+ register,
+ handleSubmit,
+ formState: { errors },
+ } = useForm();
+
+ const onSubmit = async (data: LoginFormData) => {
+ const result = await dispatch(loginAsync(data));
+
+ if (loginAsync.fulfilled.match(result)) {
+ alert('로그인에 성공했습니다!');
+ navigate('/');
+ } else {
+ alert(
+ (result.payload as string) ||
+ '로그인에 실패했습니다. 다시 시도해주세요.'
+ );
+ }
+ };
+
+ return (
+
+
+ navigate('/')}>
+
+
+
+
+
+
+ 아직 회원이 아니신가요?
+ navigate('/join')}>이메일 회원가입
+
+
+
+ );
+}
+
+const Container = styled.div`
+ background-color: #ffffff;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ height: 100vh;
+`;
+
+const InnerWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ width: 100%;
+ max-width: 24rem;
+`;
+
+const LogoWrapper = styled.div`
+ margin-bottom: 2.5rem;
+ cursor: pointer;
+`;
+
+const LogoImage = styled.img`
+ width: 150px;
+ height: 80px;
+ object-fit: contain;
+`;
+
+const Form = styled.form`
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+`;
+
+const InputWrapper = styled.div`
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ margin-bottom: 1rem;
+`;
+
+const StyledInput = styled(Input)`
+ max-width: 350px;
+ width: 100%;
+ margin: 0 auto;
+ display: block;
+`;
+
+const SubmitButton = styled.button`
+ width: 300px;
+ height: 70px;
+ background-color: #ffffff;
+ border: 1px solid #000000;
+ border-radius: 9999px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ color: #000000;
+ font-size: 18px;
+ font-weight: 400;
+ cursor: pointer;
+ margin: 0 auto;
+ margin-top: 2rem;
+
+ &:hover {
+ background-color: #e5e7eb;
+ }
+
+ &:disabled {
+ background-color: #e5e7eb;
+ cursor: not-allowed;
+ }
+`;
+
+const BottomSection = styled.div`
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ margin-top: 3.5rem;
+ gap: 1rem;
+`;
+
+const InfoText = styled.span`
+ color: #a7a7a7;
+ font-size: 12px;
+`;
+
+const LinkText = styled.span`
+ color: #000000;
+ font-size: 12px;
+ cursor: pointer;
+`;
+
+const ErrorText = styled.p`
+ color: #ef4444;
+ font-size: 0.875rem;
+ margin-bottom: 1rem;
+ text-align: left;
+ width: 100%;
+ max-width: 350px;
+`;
+
+export default LoginPage;
diff --git a/src/pages/MyPage.tsx b/src/pages/MyPage.tsx
new file mode 100644
index 0000000..7238459
--- /dev/null
+++ b/src/pages/MyPage.tsx
@@ -0,0 +1,132 @@
+import { useEffect, useState } from 'react';
+import Avatar from '@/components/ui/atoms/Avator';
+import { useSelector } from 'react-redux';
+import { Link, Outlet, useLocation } from 'react-router';
+import styled from 'styled-components';
+import { RootState } from '@/store/rootReducer';
+import { fetchUserInfo, UserData } from '@/apis/user-info.api';
+
+const MyPage = () => {
+ const location = useLocation();
+ const nickname = useSelector(
+ (state: RootState) => state.user.userInfo?.nickname
+ );
+
+ const [userData, setUserData] = useState(null);
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ if (nickname) {
+ setLoading(true);
+ fetchUserInfo(nickname)
+ .then((data) => {
+ setUserData(data);
+ setLoading(false);
+ })
+ .catch((error) => {
+ console.error('에러 발생:', error);
+ setLoading(false);
+ });
+ }
+ }, [nickname]);
+
+ if (loading) {
+ return Loading...
;
+ }
+
+ return (
+
+
+
+
+ {userData?.profile.nickname}님
+
+
+
+
+ 홈
+
+
+
+
+ 게시글
+
+
+
+
+ 좋아요한 게시글
+
+
+
+
+
+
+
+
+ );
+};
+
+export default MyPage;
+
+const MyPageContainer = styled.div`
+ display: flex;
+ width: 100%;
+ min-height: 100vh;
+`;
+
+const UserProfileSection = styled.section`
+ width: 300px;
+ min-height: 100vh;
+ position: relative;
+ padding: 20px 0;
+`;
+
+const UserContentSection = styled.section`
+ flex: 1;
+ min-height: 100vh;
+ padding: 10px;
+`;
+
+const AvatarContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ align-items: center;
+`;
+
+const UserName = styled.div`
+ font-size: 18px;
+ font-weight: bold;
+ color: black;
+ margin-top: 10px;
+`;
+
+const Navigation = styled.ul`
+ list-style: none;
+ padding: 0;
+ margin-top: 40px;
+ margin-left: 20px;
+`;
+
+const NavItem = styled.li`
+ margin: 10px 0;
+`;
+
+const StyledLink = styled(Link)<{ isActive: boolean }>`
+ text-decoration: none;
+ color: ${(props) => (props.isActive ? 'black' : 'gray')};
+ font-size: 16px;
+ &:hover {
+ color: lightgray;
+ }
+`;
diff --git a/src/routes/router.tsx b/src/routes/router.tsx
new file mode 100644
index 0000000..6feaa2b
--- /dev/null
+++ b/src/routes/router.tsx
@@ -0,0 +1,69 @@
+import Layout from '@/components/layout/Layout';
+import Scraps from '@/components/my-page/Scraps';
+import UserContents from '@/components/my-page/UserContents';
+import UserPosts from '@/components/my-page/UserPosts';
+import AdminPage from '@/pages/AdminPage';
+import HomePage from '@/pages/HomePage';
+import JoinPage from '@/pages/JoinPage';
+import LoginPage from '@/pages/LoginPage';
+import MyPage from '@/pages/MyPage';
+import ProtectedRoute from '@/admin/AdminRoute';
+import BoardWritePage from '@/pages/BoardWritePage';
+import BoardModificationPage from '@/pages/BoardModificationPage';
+
+const router = [
+ {
+ path: '/',
+ element: ,
+ children: [
+ {
+ path: '/',
+ element: ,
+ },
+ {
+ path: '/boardwrite',
+ element: ,
+ },
+ {
+ path: '/boardModification',
+ element: ,
+ },
+ {
+ path: '/mypage',
+ element: ,
+ children: [
+ {
+ path: '',
+ element: ,
+ },
+ {
+ path: 'myposts',
+ element: ,
+ },
+ {
+ path: 'scrap',
+ element: ,
+ },
+ ],
+ },
+ {
+ path: '/adminpage',
+ element: (
+
+
+
+ ),
+ },
+ ],
+ },
+ {
+ path: '/login',
+ element: ,
+ },
+ {
+ path: '/join',
+ element: ,
+ },
+];
+
+export default router;
diff --git a/src/store/rootReducer.ts b/src/store/rootReducer.ts
new file mode 100644
index 0000000..41d8039
--- /dev/null
+++ b/src/store/rootReducer.ts
@@ -0,0 +1,11 @@
+// src/app/rootReducer.ts
+import { combineReducers } from '@reduxjs/toolkit';
+import userReducer from '@/hooks/userSlice';
+
+const rootReducer = combineReducers({
+ user: userReducer,
+ // 다른 slice reducer가 있다면 여기에 추가
+});
+
+export type RootState = ReturnType;
+export default rootReducer;
diff --git a/src/store/store.ts b/src/store/store.ts
new file mode 100644
index 0000000..18da92d
--- /dev/null
+++ b/src/store/store.ts
@@ -0,0 +1,25 @@
+import { configureStore } from '@reduxjs/toolkit';
+import { persistStore, persistReducer } from 'redux-persist';
+import storage from 'redux-persist/lib/storage';
+import rootReducer from './rootReducer';
+
+const persistConfig = {
+ key: 'root',
+ storage,
+ whitelist: ['user'],
+};
+
+const persistedReducer = persistReducer(persistConfig, rootReducer);
+
+export const store = configureStore({
+ reducer: persistedReducer,
+ middleware: (getDefaultMiddleware) =>
+ getDefaultMiddleware({
+ serializableCheck: false,
+ }),
+});
+
+export const persistor = persistStore(store);
+
+// store의 타입 유추
+export type AppDispatch = typeof store.dispatch;
diff --git a/src/stories/Configure.mdx b/src/stories/Configure.mdx
new file mode 100644
index 0000000..6a53730
--- /dev/null
+++ b/src/stories/Configure.mdx
@@ -0,0 +1,364 @@
+import { Meta } from "@storybook/blocks";
+
+import Github from "./assets/github.svg";
+import Discord from "./assets/discord.svg";
+import Youtube from "./assets/youtube.svg";
+import Tutorials from "./assets/tutorials.svg";
+import Styling from "./assets/styling.png";
+import Context from "./assets/context.png";
+import Assets from "./assets/assets.png";
+import Docs from "./assets/docs.png";
+import Share from "./assets/share.png";
+import FigmaPlugin from "./assets/figma-plugin.png";
+import Testing from "./assets/testing.png";
+import Accessibility from "./assets/accessibility.png";
+import Theming from "./assets/theming.png";
+import AddonLibrary from "./assets/addon-library.png";
+
+export const RightArrow = () =>
+
+
+
+
+
+
+
+ # Configure your project
+
+ Because Storybook works separately from your app, you'll need to configure it for your specific stack and setup. Below, explore guides for configuring Storybook with popular frameworks and tools. If you get stuck, learn how you can ask for help from our community.
+
+
+
+
+
Add styling and CSS
+
Like with web applications, there are many ways to include CSS within Storybook. Learn more about setting up styling within Storybook.
+
Learn more
+
+
+
+
Provide context and mocking
+
Often when a story doesn't render, it's because your component is expecting a specific environment or context (like a theme provider) to be available.
+
Learn more
+
+
+
+
+
Load assets and resources
+
To link static files (like fonts) to your projects and stories, use the
+ `staticDirs` configuration option to specify folders to load when
+ starting Storybook.
+
Learn more
+
+
+
+
+
+
+ # Do more with Storybook
+
+ Now that you know the basics, let's explore other parts of Storybook that will improve your experience. This list is just to get you started. You can customise Storybook in many ways to fit your needs.
+
+
+
+
+
+
+
Autodocs
+
Auto-generate living,
+ interactive reference documentation from your components and stories.
+
Learn more
+
+
+
+
Publish to Chromatic
+
Publish your Storybook to review and collaborate with your entire team.
+
Learn more
+
+
+
+
Figma Plugin
+
Embed your stories into Figma to cross-reference the design and live
+ implementation in one place.
+
Learn more
+
+
+
+
Testing
+
Use stories to test a component in all its variations, no matter how
+ complex.
+
Learn more
+
+
+
+
Accessibility
+
Automatically test your components for a11y issues as you develop.
+
Learn more
+
+
+
+
Theming
+
Theme Storybook's UI to personalize it to your project.
+
Learn more
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Join our contributors building the future of UI development.
+
+
Star on GitHub
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/stories/assets/accessibility.png b/src/stories/assets/accessibility.png
new file mode 100644
index 0000000..6ffe6fe
Binary files /dev/null and b/src/stories/assets/accessibility.png differ
diff --git a/src/stories/assets/accessibility.svg b/src/stories/assets/accessibility.svg
new file mode 100644
index 0000000..107e93f
--- /dev/null
+++ b/src/stories/assets/accessibility.svg
@@ -0,0 +1 @@
+Accessibility
\ No newline at end of file
diff --git a/src/stories/assets/addon-library.png b/src/stories/assets/addon-library.png
new file mode 100644
index 0000000..95deb38
Binary files /dev/null and b/src/stories/assets/addon-library.png differ
diff --git a/src/stories/assets/assets.png b/src/stories/assets/assets.png
new file mode 100644
index 0000000..cfba681
Binary files /dev/null and b/src/stories/assets/assets.png differ
diff --git a/src/stories/assets/avif-test-image.avif b/src/stories/assets/avif-test-image.avif
new file mode 100644
index 0000000..530709b
Binary files /dev/null and b/src/stories/assets/avif-test-image.avif differ
diff --git a/src/stories/assets/context.png b/src/stories/assets/context.png
new file mode 100644
index 0000000..e5cd249
Binary files /dev/null and b/src/stories/assets/context.png differ
diff --git a/src/stories/assets/discord.svg b/src/stories/assets/discord.svg
new file mode 100644
index 0000000..d638958
--- /dev/null
+++ b/src/stories/assets/discord.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/stories/assets/docs.png b/src/stories/assets/docs.png
new file mode 100644
index 0000000..a749629
Binary files /dev/null and b/src/stories/assets/docs.png differ
diff --git a/src/stories/assets/figma-plugin.png b/src/stories/assets/figma-plugin.png
new file mode 100644
index 0000000..8f79b08
Binary files /dev/null and b/src/stories/assets/figma-plugin.png differ
diff --git a/src/stories/assets/github.svg b/src/stories/assets/github.svg
new file mode 100644
index 0000000..dc51352
--- /dev/null
+++ b/src/stories/assets/github.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/stories/assets/share.png b/src/stories/assets/share.png
new file mode 100644
index 0000000..8097a37
Binary files /dev/null and b/src/stories/assets/share.png differ
diff --git a/src/stories/assets/styling.png b/src/stories/assets/styling.png
new file mode 100644
index 0000000..d341e82
Binary files /dev/null and b/src/stories/assets/styling.png differ
diff --git a/src/stories/assets/testing.png b/src/stories/assets/testing.png
new file mode 100644
index 0000000..d4ac39a
Binary files /dev/null and b/src/stories/assets/testing.png differ
diff --git a/src/stories/assets/theming.png b/src/stories/assets/theming.png
new file mode 100644
index 0000000..1535eb9
Binary files /dev/null and b/src/stories/assets/theming.png differ
diff --git a/src/stories/assets/tutorials.svg b/src/stories/assets/tutorials.svg
new file mode 100644
index 0000000..b492a9c
--- /dev/null
+++ b/src/stories/assets/tutorials.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/stories/assets/youtube.svg b/src/stories/assets/youtube.svg
new file mode 100644
index 0000000..a7515d7
--- /dev/null
+++ b/src/stories/assets/youtube.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/styles/GlobalStyle.tsx b/src/styles/GlobalStyle.tsx
new file mode 100644
index 0000000..5332b3b
--- /dev/null
+++ b/src/styles/GlobalStyle.tsx
@@ -0,0 +1,19 @@
+import { createGlobalStyle } from 'styled-components';
+
+const GlobalStyle = createGlobalStyle`
+ *, *::before, *::after {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+html, body {
+ margin: 0;
+ padding: 0;
+ font-family: 'Pretendard-Regular', sans-serif;
+ width: 100%;
+ height: 100%;
+}
+`;
+
+export default GlobalStyle;
diff --git a/src/styles/reset.css b/src/styles/reset.css
new file mode 100644
index 0000000..6c9d5d7
--- /dev/null
+++ b/src/styles/reset.css
@@ -0,0 +1,130 @@
+/* http://meyerweb.com/eric/tools/css/reset/
+ v2.0 | 20110126
+ License: none (public domain)
+*/
+@import 'react-quill/dist/quill.snow.css';
+
+html,
+body,
+div,
+span,
+applet,
+object,
+iframe,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+blockquote,
+pre,
+a,
+abbr,
+acronym,
+address,
+big,
+cite,
+code,
+del,
+dfn,
+em,
+img,
+ins,
+kbd,
+q,
+s,
+samp,
+small,
+strike,
+strong,
+sub,
+sup,
+tt,
+var,
+b,
+u,
+i,
+center,
+dl,
+dt,
+dd,
+ol,
+ul,
+li,
+fieldset,
+form,
+label,
+legend,
+table,
+caption,
+tbody,
+tfoot,
+thead,
+tr,
+th,
+td,
+article,
+aside,
+canvas,
+details,
+embed,
+figure,
+figcaption,
+footer,
+header,
+hgroup,
+menu,
+nav,
+output,
+ruby,
+section,
+summary,
+time,
+mark,
+audio,
+video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+menu,
+nav,
+section {
+ display: block;
+}
+body {
+ line-height: 1;
+}
+ol,
+ul {
+ list-style: none;
+}
+blockquote,
+q {
+ quotes: none;
+}
+blockquote:before,
+blockquote:after,
+q:before,
+q:after {
+ content: '';
+ content: none;
+}
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
diff --git a/src/types/admindata.ts b/src/types/admindata.ts
new file mode 100644
index 0000000..55f18d6
--- /dev/null
+++ b/src/types/admindata.ts
@@ -0,0 +1,7 @@
+export interface AdminData {
+ id: number;
+ nickname: string;
+ email: string;
+ created_at: string;
+ icon: string | null;
+}
diff --git a/src/types/auth.ts b/src/types/auth.ts
new file mode 100644
index 0000000..ba3e863
--- /dev/null
+++ b/src/types/auth.ts
@@ -0,0 +1,23 @@
+export interface UserInfo {
+ id: number;
+ email: string;
+ nickname: string;
+ role: string;
+}
+
+export interface UserState {
+ isLoggedIn: boolean;
+ token: string | null;
+ userInfo: UserInfo | null;
+ loading: boolean;
+ error: string | null;
+}
+
+export interface DecodedToken {
+ id: number;
+ email: string;
+ nickname: string;
+ role: string;
+ iat: number;
+ exp: number;
+}
diff --git a/src/types/main.model.ts b/src/types/main.model.ts
new file mode 100644
index 0000000..c3ae25c
--- /dev/null
+++ b/src/types/main.model.ts
@@ -0,0 +1,25 @@
+export interface mainUsers {
+ users: string | null;
+}
+export interface mainTags {
+ id: number | null;
+ name: string;
+ isActive?: boolean;
+}
+export interface mainPosts {
+ id: number;
+ title: string;
+ content: string;
+ solved: number;
+ nickname: string;
+ created_at: string;
+ comment_count: number;
+ like_count: number;
+ view: number;
+ tags: string | null;
+}
+export interface mainData {
+ users: mainUsers;
+ tags: mainTags[];
+ posts: mainPosts[];
+}
diff --git a/src/types/postdata.ts b/src/types/postdata.ts
new file mode 100644
index 0000000..e357de7
--- /dev/null
+++ b/src/types/postdata.ts
@@ -0,0 +1,12 @@
+export interface PostData {
+ id: number;
+ title: string;
+ content: string;
+ solved: number;
+ nickname: string;
+ created_at: string;
+ comment_count: number;
+ like_count: number;
+ view: number;
+ tags: string | null;
+}
diff --git a/src/utils/token.ts b/src/utils/token.ts
new file mode 100644
index 0000000..99a666a
--- /dev/null
+++ b/src/utils/token.ts
@@ -0,0 +1,11 @@
+export function getToken(): string | null {
+ return localStorage.getItem('token');
+}
+
+export function setToken(token: string) {
+ localStorage.setItem('token', token);
+}
+
+export function removeToken() {
+ localStorage.removeItem('token');
+}
diff --git a/tsconfig.app.json b/tsconfig.app.json
index 1556f12..7183d18 100644
--- a/tsconfig.app.json
+++ b/tsconfig.app.json
@@ -20,8 +20,11 @@
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
- "noFallthroughCasesInSwitch": true
- // "noUncheckedSideEffectImports": true
+ "noFallthroughCasesInSwitch": true,
+ "baseUrl": "./",
+ "paths": {
+ "@/*": ["src/*"]
+ }
},
"include": ["src"]
}
diff --git a/vite.config.ts b/vite.config.ts
index 8b0f57b..b8cd6c4 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,7 +1,14 @@
-import { defineConfig } from 'vite'
-import react from '@vitejs/plugin-react'
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react';
+import path from 'path';
// https://vite.dev/config/
export default defineConfig({
plugins: [react()],
-})
+ resolve: {
+ alias: {
+ '@': path.resolve(__dirname, './src'),
+ '@styled-system': path.resolve(__dirname, './styled-system'),
+ },
+ },
+});